- module for LB Proxy server
authorJiří Škrábal <nykolas@ics.muni.cz>
Thu, 20 Jan 2005 12:26:12 +0000 (12:26 +0000)
committerJiří Škrábal <nykolas@ics.muni.cz>
Thu, 20 Jan 2005 12:26:12 +0000 (12:26 +0000)
19 files changed:
org.glite.lb.proxy/.Makefile.swp [new file with mode: 0644]
org.glite.lb.proxy/LICENSE [new file with mode: 0644]
org.glite.lb.proxy/Makefile [new file with mode: 0644]
org.glite.lb.proxy/build.xml [new file with mode: 0755]
org.glite.lb.proxy/build/Makefile.inc [new file with mode: 0644]
org.glite.lb.proxy/build/glite_lb_proxy [new file with mode: 0755]
org.glite.lb.proxy/config/glite-lb-dbsetup.sql [new file with mode: 0644]
org.glite.lb.proxy/project/MultiStruct.pm [new file with mode: 0644]
org.glite.lb.proxy/project/StructField.pm [new file with mode: 0644]
org.glite.lb.proxy/project/at3 [new file with mode: 0644]
org.glite.lb.proxy/project/build.properties [new file with mode: 0644]
org.glite.lb.proxy/project/configure.properties.xml [new file with mode: 0644]
org.glite.lb.proxy/project/events.T [new file with mode: 0644]
org.glite.lb.proxy/project/properties.xml [new file with mode: 0755]
org.glite.lb.proxy/project/status.T [new file with mode: 0644]
org.glite.lb.proxy/project/tar_exclude [new file with mode: 0644]
org.glite.lb.proxy/project/types.T [new file with mode: 0644]
org.glite.lb.proxy/project/version.properties [new file with mode: 0644]
org.glite.lb.proxy/src/lbproxy.c [new file with mode: 0644]

diff --git a/org.glite.lb.proxy/.Makefile.swp b/org.glite.lb.proxy/.Makefile.swp
new file mode 100644 (file)
index 0000000..c4f1255
Binary files /dev/null and b/org.glite.lb.proxy/.Makefile.swp differ
diff --git a/org.glite.lb.proxy/LICENSE b/org.glite.lb.proxy/LICENSE
new file mode 100644 (file)
index 0000000..259a91f
--- /dev/null
@@ -0,0 +1,69 @@
+LICENSE file for EGEE Middleware\r
+================================\r
+\r
+Copyright (c) 2004 on behalf of the EU EGEE Project: \r
+The European Organization for Nuclear Research (CERN), \r
+Istituto Nazionale di Fisica Nucleare (INFN), Italy\r
+Datamat Spa, Italy\r
+Centre National de la Recherche Scientifique (CNRS), France\r
+CS Systeme d'Information (CSSI), France\r
+Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden\r
+Universiteit van Amsterdam (UvA), Netherlands\r
+University of Helsinki (UH.HIP), Finlan\r
+University of Bergen (UiB), Norway\r
+Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom\r
+\r
+Redistribution and use in source and binary forms, with or without\r
+modification, are permitted provided that the following conditions are\r
+met: \r
+\r
+1. Redistributions of source code must retain the above copyright\r
+notice, this list of conditions and the following disclaimer.\r
+\r
+2. Redistributions in binary form must reproduce the above copyright\r
+notice, this list of conditions and the following disclaimer in the\r
+documentation and/or other materials provided with the distribution.\r
+\r
+3. The end-user documentation included with the redistribution, if\r
+any, must include the following acknowledgment: "This product includes\r
+software developed by The EU EGEE Project (http://cern.ch/eu-egee/)."\r
+Alternatively, this acknowledgment may appear in the software itself, if\r
+and wherever such third-party acknowledgments normally appear.\r
+\r
+4. The names EGEE and the EU EGEE Project must not be\r
+used to endorse or promote products derived from this software without\r
+prior written permission. For written permission, please contact\r
+<email address>.\r
+\r
+5. You are under no obligation whatsoever to provide anyone with any\r
+bug fixes, patches, or upgrades to the features, functionality or\r
+performance of the Software ("Enhancements") that you may develop over\r
+time; however, if you choose to provide your Enhancements to The EU\r
+EGEE Project, or if you choose to otherwise publish or distribute your\r
+Enhancements, in source code form without contemporaneously requiring\r
+end users of The EU EGEE Proejct to enter into a separate written license\r
+agreement for such Enhancements, then you hereby grant The EU EGEE Project\r
+a non-exclusive, royalty-free perpetual license to install, use, copy,\r
+modify, prepare derivative works, incorporate into the EGEE Middleware\r
+or any other computer software, distribute, and sublicense your\r
+Enhancements or derivative works thereof, in binary and source code\r
+form (if any), whether developed by The EU EGEE Project or third parties.\r
+\r
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED\r
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+DISCLAIMED. IN NO EVENT SHALL PROJECT OR ITS CONTRIBUTORS BE LIABLE\r
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\r
+BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\r
+OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\r
+IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+\r
+This software consists of voluntary contributions made by many\r
+individuals on behalf of the EU EGEE Prject. For more information on The\r
+EU EGEE Project, please see http://cern.ch/eu-egee/. For more information on\r
+EGEE Middleware, please see http://egee-jra1.web.cern.ch/egee-jra1/\r
+\r
+\r
diff --git a/org.glite.lb.proxy/Makefile b/org.glite.lb.proxy/Makefile
new file mode 100644 (file)
index 0000000..aa66bc6
--- /dev/null
@@ -0,0 +1,134 @@
+# defaults
+top_srcdir=.
+builddir=build
+top_builddir=${top_srcdir}/${builddir}
+stagedir=.
+distdir=.
+globalprefix=glite
+lbprefix=lb
+package=glite-lb-server
+version=0.2.0
+PREFIX=/opt/glite
+
+glite_location=/opt/glite
+globus_prefix=/opt/globus
+nothrflavour=gcc32
+thrflavour=gcc32pthr
+expat_prefix=/opt/expat
+ares_prefix=/opt/ares
+gsoap_prefix=/opt/gsoap
+
+-include Makefile.inc
+-include ../Makefile.inc
+
+CC=gcc
+YACC=bison -y
+
+VPATH=${top_srcdir}/src:${top_srcdir}/test:${top_srcdir}/examples:${top_srcdir}/project
+AT3=perl -I${top_srcdir}/project ${top_srcdir}/project/at3
+
+TEST_LIBS:=-L${cppunit}/lib -lcppunit
+TEST_INC:=-I${cppunit}/include
+
+SUFFIXES = .T 
+
+DEBUG:=-g -O0 -Wall
+
+CFLAGS:= ${DEBUG} \
+       -DVERSION=\"${version}\" \
+       -I${stagedir}/include -I${top_srcdir}/src -I. \
+       -I${expat_prefix}/include \
+       -I${ares_prefix}/include \
+       -I${gsoap_prefix}/include \
+       ${COVERAGE_FLAGS} \
+       -I${mysql_prefix}/include -I${mysql_prefix}/include/mysql \
+       -I${globus_prefix}/include/${nothrflavour} \
+       -I${gridsite_prefix}/include -I${globus_prefix}/include/${nothrflavour}/openssl \
+       -D_GNU_SOURCE
+
+
+LINK:=libtool --mode=link ${CC} ${LDFLAGS} 
+LINKXX:=libtool --mode=link ${CXX} ${LDFLAGS} 
+INSTALL:=libtool --mode=install install
+LINKXX:=libtool --mode=link  ${CXX} -rpath ${stagedir}/lib ${LDFLAGS}
+
+GLOBUS_LIBS:= -L${globus_prefix}/lib \
+       -lglobus_common_${nothrflavour} \
+       -lglobus_gssapi_gsi_${nothrflavour} \
+
+ifneq (${mysql_prefix},/usr)
+       myslqlib := -L${mysql_prefix}/lib
+endif
+
+ifneq (${expat_prefix},/usr)
+       expatlib := -L${expat_prefix}/lib
+endif
+
+EXT_LIBS:= -L${ares_prefix}/lib -lares \
+       ${myslqlib} -lmysqlclient -lz\
+       ${expatlib} -lexpat \
+       ${GLOBUS_LIBS}
+
+SRVBONES_LIB:= -L${stagedir}/lib -lglite_lb_server_bones
+COMMON_LIB:= -L${stagedir}/lib -lglite_lb_common_${nothrflavour}
+LB_SERVER_SHARE_LIB:= -L${stagedir}/lib -lglite_lb_server
+LB_PROXY_COMMON_LIB:= -L${stagedir}/lib -lglite_lb_common_${nothrflavour}
+
+
+LB_PROXY_OBJS:= lbproxy.o
+
+glite_lb_proxy: ${LB_PROXY_OBJS} 
+       ${LINK} -o $@ ${LB_PROXY_OBJS} ${LB_SERVER_SHARE_LIB} ${COMMON_LIB} ${SRVBONES_LIB} ${EXT_LIBS}
+
+default all: compile
+
+compile: glite_lb_proxy
+
+check: compile
+       -echo No test so far
+
+examples: 
+
+doc:
+
+stage: compile
+       $(MAKE) install PREFIX=${stagedir} DOSTAGE=yes
+
+dist: distsrc distbin
+
+distsrc:
+       mkdir -p ${top_srcdir}/${package}-${version}
+       cd ${top_srcdir} && GLOBIGNORE="${package}-${version}" && cp -Rf * ${package}-${version}
+       cd ${top_srcdir} && tar -czf ${distdir}/${package}-${version}_src.tar.gz --exclude-from=project/tar_exclude ${package}-${version}
+       rm -rf ${top_srcdir}/${package}-${version}
+
+distbin:
+       $(MAKE) install PREFIX=`pwd`/tmpbuilddir${stagedir}
+       save_dir=`pwd`; cd tmpbuilddir${stagedir} && tar -czf $$save_dir/${top_srcdir}/${distdir}/${package}-${version}_bin.tar.gz *; cd $$save_dir
+       rm -rf tmpbuilddir
+        
+install:
+       -mkdir -p ${PREFIX}/bin ${PREFIX}/etc ${PREFIX}/etc/init.d
+       -mkdir -p ${PREFIX}/share/doc/${package}-${version}
+       ${INSTALL} -m 644 ${top_srcdir}/LICENSE ${PREFIX}/share/doc/${package}-${version}
+       ${INSTALL} -m 755 glite_lb_proxy ${PREFIX}/bin/glite-lb-proxy
+       ${INSTALL} -m 644 ${top_srcdir}/config/glite-lb-dbsetup.sql ${PREFIX}/etc
+
+clean:
+
+%.c: %.c.T
+       rm -f $@
+       ${AT3} $< >$@ || rm -f $@
+       chmod -w $@ >/dev/null
+
+%.o: %.y
+       ${YACC} -d ${YFLAGS} $<
+       mv y.tab.c $*.c
+       mv y.tab.h $*.h
+       ${CC} -c ${CFLAGS} $*.c
+       rm $*.c
+
+%.cpp: %.cpp.T
+       rm -f $@
+       ${AT3} $< >$@ || rm -f $@
+       chmod -w $@ >/dev/null
diff --git a/org.glite.lb.proxy/build.xml b/org.glite.lb.proxy/build.xml
new file mode 100755 (executable)
index 0000000..363037e
--- /dev/null
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+       Copyright (c) 2004 on behalf of the EU EGEE Project: 
+       The European Organization for Nuclear Research (CERN), 
+       Istituto Nazionale di Fisica Nucleare (INFN), Italy
+       Datamat Spa, Italy
+       Centre National de la Recherche Scientifique (CNRS), France
+       CS Systeme d'Information (CSSI), France
+       Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden
+       Universiteit van Amsterdam (UvA), Netherlands
+       University of Helsinki (UH.HIP), Finland
+       University of Bergen (UiB), Norway
+       Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom
+
+       Build file for the GLite LB Proxy module
+       
+       Authors: Jiri Skrabal <nykolas@ics.muni.cz>
+       Release: $Name$
+
+       Revision history:
+       
+-->
+
+<project name="proxy" default="dist">
+       
+       <!-- =========================================
+                Builds the GLite LB Proxy Module
+            ========================================= -->
+       
+       <!-- =========================================
+            Import properties (order is important)
+            ========================================= -->
+
+       <!-- import baseline & user properties -->
+       <import file="../org.glite/project/baseline.properties.xml" />
+
+       <!-- import component build properties,
+                       component properties &
+                       component common properties -->
+       <import file="./project/properties.xml"/>
+       
+       <!-- import subsystem build properties,
+                       subsystem properties &
+                       subsystem common properties -->
+       <import file="${subsystem.properties.file}"/>
+
+       <!-- import global build properties &
+                       global properties -->
+       <import file="${global.properties.file}" />
+               
+       <!-- =========================================
+                Load dependency property files (order is important)
+            ========================================= -->
+       <property file="${user.dependencies.file}"/>
+       <property file="${component.dependencies.file}" />
+       <property file="${subsystem.dependencies.file}" />
+       <property file="${global.dependencies.file}"/>
+       
+       <!-- =========================================
+                Load configure options (order is important)
+            ========================================= -->
+       <import file="${global.configure.options.file}"/>
+       <import file="${component.configure.options.file}"/>
+
+       <!-- =========================================
+                Import task definitions (order is important)
+            ========================================= -->
+       <import file="${subsystem.taskdefs.file}" />
+       <import file="${global.taskdefs.file}" />
+                       
+       <!-- =========================================
+                Load common targets
+            ========================================= -->
+       <import file="${global.targets-simple_make.file}" />
+
+       <!-- =========================================
+                Load version file 
+            ========================================= -->
+       <property file="${module.version.file}"/>
+               
+       <!-- ==============================================
+                Local private targets
+            ============================================== -->
+       
+       <target name="localinit"
+               description="Module specific initialization tasks">
+        <!-- Copy support files from the subsystem project to the component project-->
+               <copy toDir="${module.project.dir}">
+                       <fileset dir="${subsystem.project.dir}">
+                               <include name="at3" />
+                               <include name="*.T" />
+                               <include name="*.pm" />
+                       </fileset>
+               </copy> 
+               <antcall target="lbmakefiles" />
+       </target>
+               
+       <target name="localcompile"
+               description="Module specific compile tasks">
+       </target>
+       
+       <target name="localclean"
+               description="Module specific cleaning tasks">
+               <delete>
+                       <fileset dir="${module.project.dir}">
+                               <include name="at3" />
+                               <include name="*.T" />
+                               <include name="*.pm" />
+                       </fileset>
+               </delete>       
+       </target>
+       
+       <!-- =========================================
+            RPM settings
+            ========================================= -->
+
+       <property name="build.package.summary" value="L&amp;B Proxy server" />
+       <property name="build.package.description" value=" The daemon
+installed at the ??? machine.&#xA;It is responsible for accepting events from
+???, storing them in RDBMS, forwarding then to the real L&amp;B server&#xA;and performing queries on client requests
+(job status, job log etc.).&#xA;Also includes purge utilities
+to remove (and optionally archive) inactive&#xA;data from
+the database and to change database index configuration." />
+
+</project>             
diff --git a/org.glite.lb.proxy/build/Makefile.inc b/org.glite.lb.proxy/build/Makefile.inc
new file mode 100644 (file)
index 0000000..e8788fd
--- /dev/null
@@ -0,0 +1,21 @@
+
+top_srcdir=..
+builddir=build
+stagedir=/home/nykolas/work/Egee/glite/stage
+distdir=../dist
+globalprefix=glite
+lbprefix=lb
+package=glite-lb-proxy
+PREFIX=/opt/glite
+version=1.1.0
+glite_location=/home/nykolas/work/Egee/glite/stage
+globus_prefix=/software/globus-2.2.4
+thrflavour=gcc32dbgpthr
+nothrflavour=gcc32dbg
+expat_prefix=/home/nykolas/work/Egee/repository/expat/1.95.7/rhel30_gcc32
+ares_prefix=/packages/run/ares-1.1.1
+mysql_prefix=/home/nykolas/work/Egee/repository/mysql/4.0.20/rhel30_gcc32
+cppunit=/home/nykolas/work/Egee/repository/cppunit/1.10.2/rhel30_gcc32
+gridsite_prefix=/home/nykolas/work/Egee/glite/stage
+gsoap_prefix=/software/gsoap-2.6
+                       
\ No newline at end of file
diff --git a/org.glite.lb.proxy/build/glite_lb_proxy b/org.glite.lb.proxy/build/glite_lb_proxy
new file mode 100755 (executable)
index 0000000..5b01a45
Binary files /dev/null and b/org.glite.lb.proxy/build/glite_lb_proxy differ
diff --git a/org.glite.lb.proxy/config/glite-lb-dbsetup.sql b/org.glite.lb.proxy/config/glite-lb-dbsetup.sql
new file mode 100644 (file)
index 0000000..af04974
--- /dev/null
@@ -0,0 +1,112 @@
+create table jobs (
+       jobid           char(32)        binary not null,
+       dg_jobid        varchar(255)    binary not null,
+       userid          char(32)        binary not null,
+       aclid           char(32)        binary null,
+
+       primary key (jobid),
+       unique (dg_jobid),
+       index (userid)
+);
+
+create table users (
+       userid          char(32)        binary not null,
+       cert_subj       varchar(255)    binary not null,
+
+       primary key (userid),
+       unique (cert_subj)
+);
+
+create table events (
+       jobid           char(32)        binary not null,
+       event           int             not null,
+       code            int             not null,
+       prog            varchar(255)    binary not null,
+       host            varchar(255)    binary not null,
+       time_stamp      datetime        not null,
+       userid          char(32)        binary null,
+       usec            int             null,
+       level           int             null,
+
+       arrived         datetime        not null,
+       
+
+       primary key (jobid,event),
+       index (time_stamp),
+       index (host),
+       index (arrived)
+);
+
+create table short_fields (
+       jobid           char(32)        binary not null,
+       event           int             not null,
+       name            varchar(200)    binary not null,
+       value           varchar(255)    binary null,
+
+       primary key (jobid,event,name)
+);
+
+create table long_fields (
+       jobid           char(32)        binary not null,
+       event           int             not null,
+       name            varchar(200)    binary not null,
+       value           mediumblob      null,
+
+       primary key (jobid,event,name)
+);
+
+create table states (
+       jobid           char(32)        binary not null,
+       status          int             not null,
+       seq             int             not null,
+       int_status      mediumblob      not null,
+       version         varchar(32)     not null,
+       parent_job      varchar(32)     binary not null,
+
+       primary key (jobid),
+       index (parent_job)
+       
+);
+
+create table status_tags (
+       jobid           char(32)        binary not null,
+       seq             int             not null,
+       name            varchar(200)    binary not null,
+       value           varchar(255)    binary null,
+
+       primary key (jobid,seq,name)
+);
+
+create table server_state (
+       prefix          varchar(100)    not null,
+       name            varchar(100)    binary not null,
+       value           varchar(255)    binary not null,
+
+       primary key (prefix,name)
+);
+
+create table acls (
+       aclid           char(32)        binary not null,
+       value           mediumblob      not null,
+       refcnt          int             not null,
+
+       primary key (aclid)
+);
+
+create table notif_registrations (
+       notifid         char(32)        binary not null,
+       destination     varchar(200)    not null,
+       valid           datetime        not null,
+       userid          char(32)        binary not null,
+       conditions      mediumblob      not null,
+
+       primary key (notifid)
+);
+
+create table notif_jobs (
+       notifid         char(32)        binary not null,
+       jobid           char(32)        binary not null,
+
+       primary key (notifid,jobid),
+       index (jobid)
+);
diff --git a/org.glite.lb.proxy/project/MultiStruct.pm b/org.glite.lb.proxy/project/MultiStruct.pm
new file mode 100644 (file)
index 0000000..9cd847c
--- /dev/null
@@ -0,0 +1,191 @@
+package MultiStruct;
+
+use StructField;
+
+sub new {
+       shift;
+       my $self = {};
+       $self->{comments} = {}; # typ->comment
+       $self->{fields} = {};   # typ->{ name->StructField, ... }
+       $self->{order} = {};
+
+       bless $self;
+}
+
+sub selectType {
+       my $self = shift;
+       my $type = shift;
+       $self->{type} = $type;
+       1;
+}
+
+sub addType {
+       my $self = shift;
+       my $type = shift;
+       my $comment = shift;
+       $self->selectType($type);
+       $self->{comments}->{$type} = $comment;
+       $self->{fields}->{$type} = {};
+       1;
+}
+
+sub selectField {
+       my $self = shift;
+       $self->{field} = shift;
+       $self->getField;
+}
+
+sub addField {
+       my $self = shift;
+       my $field = shift;
+       
+       die "unselected type" unless $self->{type};
+       $self->{fields}->{$self->{type}}->{$field->{name}} = $field;
+       $self->selectField($field->{name});
+       1;
+}
+
+sub getField {
+       my $self = shift;
+       my $f = $self->{fields}->{$self->{type}}->{$self->{field}};
+       return $f ? $f : $self->{fields}->{_common_}->{$self->{field}};
+}
+
+sub load {
+       my $self = shift;
+       my $fh = shift;
+       local $_;
+
+       while ($_ = <$fh>) {
+
+               chomp;
+               s/#.*$//;
+               next if /^\s*$/;
+
+               if (/^\@type\s+(\S+)\s*(.*$)$/) {
+                       $self->addType($1,$2);
+                       $self->{order}->{$1} = $.;
+                       next;
+               }
+
+               s/^\s*//;
+               my ($ftype,$fname,$comment) = split /\s+/,$_,3;
+               if ($ftype eq '_code_') {
+                       my $f = $self->getField();
+                       addCode $f $fname,$comment;
+               }
+               elsif ($ftype eq '_alias_') {
+                       my $f = $self->getField();
+                       addAlias $f $fname,$comment;
+               }
+               elsif ($ftype eq '_special_') {
+                       my $f = $self->getField();
+                       addSpecial $f $fname;
+               }
+               elsif ($ftype eq '_null_') {
+                       my $f = $self->getField();
+                       setNull $f $fname;
+               }
+               elsif ($ftype eq '_optional_') {
+                       my $f = $self->getField();
+                       $f->{optional} = 1;
+               }
+               elsif ($ftype eq '_index_') {
+                       my $f = $self->getField();
+                       $f->{index} = 1;
+               }
+               else {
+                       my $f = new StructField $fname,$ftype,$comment,$.;
+                       $self->addField($f);
+               }
+       }
+}
+
+sub getTypes {
+       my $self = shift;
+       my @out;
+       local $_;
+
+       for (keys %{$self->{fields}}) {
+               push @out,$_ unless $_ eq '_common_';
+       }
+       @out;
+}
+
+sub getTypesOrdered {
+       my $self = shift;
+       my @names = getTypes $self;
+
+       sort {
+               my $oa = $self->{order}->{$a};
+               my $ob = $self->{order}->{$b};
+               $oa <=> $ob;
+       } @names;
+}
+
+sub getTypeComment {
+       my $self = shift;
+       my $type = shift || $self->{type};
+       $self->{comments}->{$type};
+}
+
+sub getFieldComment {
+       my $self = shift;
+       my $fname = shift;
+       $self->{fields}->{$self->{type}}->{$fname}->{comment};
+}
+
+sub getFields {
+       my $self = shift;
+       keys %{$self->{fields}->{$self->{type}}};
+}
+
+sub getFieldsOrdered {
+       my $self = shift;
+       my @names = $self->getFields;
+       sort {
+               my $oa = $self->selectField($a)->{order};
+               my $ob = $self->selectField($b)->{order};
+               $oa <=> $ob;
+       } @names;
+}
+
+sub getFieldOccurence {
+       my $self = shift;
+       my $fname = shift;
+       my @out;
+       local $_;
+
+       for (keys %{$self->{fields}}) {
+               push @out,$_ if $self->{fields}->{$_}->{$fname};
+       }
+       @out;
+}
+
+sub getAllFields {
+       my $self = shift;
+       my %out;
+       local $_;
+
+       for my $t (values %{$self->{fields}}) {
+               $out{$_->{name}} = 1 for (values %$t);
+       }
+       keys %out;
+}
+
+sub getAllFieldsOrdered {
+       my $self = shift;
+       my @names = getAllFields $self;
+
+       sort {
+               my @occ = $self->getFieldOccurence($a);
+               $self->selectType($occ[0]);
+               my $oa = $self->selectField($a)->{order};
+               @occ = $self->getFieldOccurence($b);
+               $self->selectType($occ[0]);
+               my $ob = $self->selectField($b)->{order};
+               $oa <=> $ob;
+       } @names;
+}
+
+1;
diff --git a/org.glite.lb.proxy/project/StructField.pm b/org.glite.lb.proxy/project/StructField.pm
new file mode 100644 (file)
index 0000000..95d33b8
--- /dev/null
@@ -0,0 +1,116 @@
+package StructField;
+
+$lang = 'C';
+1;
+
+sub new {
+       shift;
+       my $self = {};
+       $self->{name} = shift;
+       $self->{type} = shift;
+       $self->{comment} = shift;
+       $self->{order} = shift;
+       $self->{null} = $main::DefaultNullValue{$self->{type}};
+       bless $self;
+}
+
+sub addCode {
+       my $self = shift;
+       my $code = shift;
+       my $comment = shift;
+       push @{$self->{codes}},{name=>$code,comment=>$comment};
+       1;
+}
+
+sub addSpecial {
+       my $self = shift;
+       my $special = shift;
+       $self->{special} = $special;
+       1;
+}
+
+sub addAlias {
+       my $self = shift;
+       my $name = shift;
+       my $lang = shift;
+       $self->{aliases}->{$lang} = $name;
+       1;
+}
+
+sub hasAlias {
+       my $self = shift;
+       my $lang = shift;
+       return $self->{aliases}->{$lang} ? 1 : 0;
+}
+
+sub getName {
+       my $self = shift;
+       my $lang = shift || $lang;
+       $self->{aliases}->{$lang} || $self->{name};
+#      return $self->{aliases}->{$lang} ? $self->{aliases}->{$lang} : $self->{name};
+}
+
+sub getComment {
+       my $self = shift;
+       $self->{comment};
+}
+
+sub getDefaultNullValue {
+       my $self = shift;
+       $self->{null};
+}
+
+sub toString {
+       my $self = shift;
+       my $src = shift;
+       my $dst = shift;
+
+       eval $main::toString{$lang}->{$self->{type}};
+}
+
+sub fromString {
+       my $self = shift;
+       my $src = shift;
+       my $dst = shift;
+
+       eval $main::fromString{$lang}->{$self->{type}};
+}
+
+sub isNULL {
+       my $self = shift;
+       my $a = shift;
+       my $b = $self->{null};
+
+       eval $main::compare{$lang}->{$self->{type}};
+}
+
+sub isnotNULL {
+       my $self = shift;
+       my $src = shift;
+
+       '!('.$self->isNULL($src).')';
+}
+
+sub compare {
+       my $self = shift;
+       my $a = shift;
+       my $b = shift;
+       eval $main::compare{$lang}->{$self->{type}};
+}
+
+sub toFormatString {
+       my $self = shift;
+
+       eval $main::toFormatString{$lang}->{$self->{type}};
+}
+
+sub setNull {
+       my $self = shift;
+       $self->{null} = shift;
+}
+
+sub getType {
+       my $self = shift;
+
+       eval $main::types{$lang}->{$self->{type}};
+}
diff --git a/org.glite.lb.proxy/project/at3 b/org.glite.lb.proxy/project/at3
new file mode 100644 (file)
index 0000000..8ff52ec
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/perl -w
+
+use File::Basename;
+my $dir;
+BEGIN{
+       $dir = dirname $0;
+}
+
+my $lines = $ENV{AT3_LINES};
+
+use lib $dir;
+use MultiStruct;
+require 'types.T';
+
+my $eventsn;
+for (@INC) { 
+       if (-f "$_/events.T") {
+               $eventsn="$_/events.T";
+               last;
+       }
+}
+
+my $statusn;
+for (@INC) {
+       if (-f "$_/status.T") {
+               $statusn = "$_/status.T";
+               last;
+       }
+}
+
+my $indent = '';
+
+my $event = new MultiStruct;
+my $status = new MultiStruct;
+
+sub gen {
+       local $_ = shift;
+
+       s/^\n!//;
+       s/\n!/\n/g;
+       print $_;
+}
+
+
+open EVENTS,$eventsn or die "$eventsn: $!\n";
+$event->load(\*EVENTS);
+close EVENTS;
+
+open STATUS,$statusn or die "$statusn: $!\n";
+$status->load(\*STATUS);
+close STATUS;
+
+my $code;
+my $startcode;
+while (<>) {
+       chomp;
+       if (/^\@\@\@LANG: (\S+)$/) {
+               $StructField::lang = $1;
+               next;
+       }
+
+       if ($code) {
+               if (/^\@\@\@}$/) {
+                       $code .= "1;\n";
+                       print "#line $startcode \"$ARGV\"\n/* begin */\n" if $lines;
+                       eval $code or warn "eval: $@ at $ARGV:$.\n";
+                       my $nxtline = $.+1;
+                       print "/* end */\n#line $nxtline \"$ARGV\"\n" if $lines;
+                       undef $code;
+               }
+               else { $code .= $_."\n"; }
+       }
+       else {
+               if (/^\@\@\@{$/) {
+                       $startcode = $.;
+                       $code = "\n";
+               }
+               elsif (/^\@\@\@AUTO$/) {
+                       print qq{
+  !! Automatically generated file
+  !! Do not edit, your changes will be discarded upon build
+  !! Change the corresponding template file $ARGV
+
+};
+                       print "#line $. \"$ARGV\"\n" if $lines;
+               }
+               else {
+                       print "$_\n";
+               }
+       }
+}
+
+# print $event_common{prog}->copy('bla','hu');
diff --git a/org.glite.lb.proxy/project/build.properties b/org.glite.lb.proxy/project/build.properties
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/org.glite.lb.proxy/project/configure.properties.xml b/org.glite.lb.proxy/project/configure.properties.xml
new file mode 100644 (file)
index 0000000..9238a36
--- /dev/null
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+       Copyright (c) 2004 on behalf of the EU EGEE Project: 
+       The European Organization for Nuclear Research (CERN), 
+       Istituto Nazionale di Fisica Nucleare (INFN), Italy
+       Datamat Spa, Italy
+       Centre National de la Recherche Scientifique (CNRS), France
+       CS Systeme d'Information (CSSI), France
+       Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden
+       Universiteit van Amsterdam (UvA), Netherlands
+       University of Helsinki (UH.HIP), Finland
+       University of Bergen (UiB), Norway
+       Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom
+
+       Configuration options for the GLite LB Proxy module
+       
+       Authors: Jiri Skrabal <nykolas@ics.muni.cz>
+
+       Revision history:
+       
+       
+-->
+
+       <!-- ======================================================
+         Define extra properties here ...
+         ====================================================== -->
+        
+       <project name="LB Server configuration options">                                                                        
+               <target name="lbmakefiles">
+                       <exec executable="ln" failonerror="true">
+                               <arg line="-fs ${component.dir}/Makefile ${module.build.dir}/Makefile"/>
+                       </exec>
+                       <echo file="${module.build.dir}/Makefile.inc">
+top_srcdir=..
+builddir=build
+stagedir=${stage.abs.dir}
+distdir=${dist.dir}
+globalprefix=${global.prefix}
+lbprefix=${subsystem.prefix}
+package=${module.package.name}
+PREFIX=${install.dir}
+version=${module.version}
+glite_location=${with.glite.location}
+globus_prefix=${with.globus.prefix}
+thrflavour=${with.globus.thr.flavor}
+nothrflavour=${with.globus.nothr.flavor}
+expat_prefix=${with.expat.prefix}
+ares_prefix=${with.ares.prefix}
+mysql_prefix=${with.mysql.prefix}
+cppunit=${with.cppunit.prefix}
+gridsite_prefix=${with.gridsite.prefix}
+gsoap_prefix=${with.gsoap.prefix}
+                       </echo>
+           </target>
+       </project>
diff --git a/org.glite.lb.proxy/project/events.T b/org.glite.lb.proxy/project/events.T
new file mode 100644 (file)
index 0000000..b8e5399
--- /dev/null
@@ -0,0 +1,183 @@
+@type _common_
+       timeval timestamp       timestamp of event generation
+       _alias_ date            ULM
+       timeval arrived         timestamp of event store
+       _alias_ arr_date        ULM
+       _optional_
+       string  host            hostname of the machine where the event was generated
+       _alias_ host            ULM
+       int     level           logging level (system, debug, ...)
+       _alias_ lvl             ULM
+       _code_  EMERGENCY       emergency
+       _code_  ALERT           alert
+       _code_  ERROR           error
+       _code_  WARNING         warning
+       _code_  AUTH            authentication
+       _code_  SECURITY        security
+       _code_  USAGE           usage
+       _code_  SYSTEM          system
+       _code_  IMPORTANT       important
+       _code_  DEBUG           debug
+       int     priority        message priority (yet 0 for asynchronous and 1 for synchronous transfers)
+       _null_  -1
+       jobid   jobId           DataGrid job id of the source job
+       string  seqcode         sequence code assigned to the event
+       string  user            identity (cert. subj.) of the generator
+       logsrc  source          source (WMS component) which generated this event
+#      string  prog            name of program ("EDG WMS" of name of the application)
+       string  src_instance    instance of WMS component (e.g. service communication endpoint)
+       _optional_
+
+@type Transfer         Start, success, or failure of job transfer to another component
+       logsrc  destination     destination where the job is being transfered to
+       string  dest_host       destination hostname
+       string  dest_instance   destination instance
+       _optional_
+       string  job             job description in receiver language
+       int     result          result of the attempt
+       _code_  START           the sending component has started or is about to start the transfer
+       _code_  OK              job was sent successfully
+       _code_  REFUSED         job was refused by the other component
+       _code_  FAIL            transfer failed for other reason than explicit refusal (eg. network timeout)
+       string  reason          detailed description of transfer, especially reason of failure
+       _optional_
+       string  dest_jobid      destination internal jobid
+       _optional_
+
+@type Accepted         Accepting job (successful couterpart to Transfer)
+       logsrc  from            where was the job received from
+       string  from_host       sending component hostname
+       string  from_instance   sending component instance
+       _optional_
+       string  local_jobid     new jobId (Condor, Globus ...) assigned by the receiving component
+
+@type Refused          Refusing job (unsuccessful couterpart to Transfer)
+       logsrc  from            where was the job received from
+       string  from_host       sending component hostname
+       string  from_instance   sending component instance
+       _optional_
+       string  reason          reason of refusal
+
+@type EnQueued         The job has been enqueued in an inter-component queue
+       string  queue           destination queue
+       string  job             job description in receiver language
+       int     result          result of the attempt
+       _code_  START           the sending component has started or is about to start the transfer
+       _code_  OK              job was sent successfully
+       _code_  REFUSED         job was refused by the other component
+       _code_  FAIL            transfer failed for other reason than explicit refusal (eg. network timeout)
+       string  reason          detailed description of transfer, especially reason of failure
+
+@type DeQueued         The job has been dequeued from an inter-component queue
+       string  queue           queue name
+       string  local_jobid     new jobId assigned by the receiving component
+
+@type HelperCall       Helper component is called
+       string  helper_name     name of the called component
+       string  helper_params   parameters of the call
+       int     src_role        whether the logging component is called or calling one
+       _code_  CALLING         the logging component is caller
+       _code_  CALLED          the logging component is callee
+
+@type HelperReturn     Helper component is returning the control
+       string  helper_name     name of the called component
+       string  retval          returned data
+       int     src_role        whether the logging component is called or calling one
+       _code_  CALLING         the logging component is caller
+       _code_  CALLED          the logging component is callee
+
+@type Running          Executable started
+       string  node            worker node where the executable is run
+
+@type Resubmission     Result of resubmission decision
+       int     result          result code
+       _code_  WILLRESUB       will be resubmitted
+       _code_  WONTRESUB       will not be resubmitted
+       string  reason          reason for the decision
+       string  tag             value of the attribute on which the decision is based
+
+@type Done             Execution terminated (normally or abnormally)
+       int     status_code     way of termination
+       _code_  OK              terminated by itself
+       _code_  FAILED          disappeared from LRMS
+       _code_  CANCELLED       cancelled by user request
+       string  reason          reason for the change
+       int     exit_code       process exit code
+       _null_  -1
+
+@type Cancel           Cancel operation has been attempted on the job
+       int     status_code     classification of the cancel
+       _code_  REQ             request acknowledged
+       _code_  REFUSE          request declined by this component
+       _code_  DONE            request completed by whole WMS
+       _code_  ABORT           request refused by whole WMS
+       string  reason  detailed description
+
+@type Abort            Job aborted by system
+       string  reason          reason of abort
+
+@type Clear            Job cleared, output sandbox removed
+       int     reason          why the job was cleared
+       _code_  USER            user retrieved output sandbox
+       _code_  TIMEOUT         timed out, resource purge forced
+       _code_  NOOUTPUT        no output was generated
+
+@type Purge            Job is purged from bookkepping server
+
+@type Match            Matching CE found
+       string  dest_id         Id of the destination CE/queue
+       
+@type Pending          No match found yet
+       string  reason          why matching CE cannot be found
+
+@type RegJob           New job registration
+       string  jdl             job description
+       string  ns              NetworkServer handling the job
+       jobid   parent          jobid of parent job
+       _optional_
+
+       int     jobtype         job type
+       _code_  SIMPLE          simple job
+       _code_  DAG             dag (containing static set of subjobs)
+       _code_  PARTITIONABLE   partitionable (may become partitioned)
+       _code_  PARTITIONED     partitioned (dynamically created dag)
+       
+       int     nsubjobs        number of subjobs
+       _optional_
+       string  seed            seed for subjob id generation
+       _optional_
+
+@type Chkpt            Application-specific checkpoint record
+       string  tag             checkpoint tag
+       string  classad         checkpoint value
+
+@type Listener                 Listening network port for interactive control
+       string  svc_name        port instance name
+       string  svc_host        hostname
+       port    svc_port        port number
+
+@type CurDescr         current state of job processing (optional event)
+       string  descr           description of current job transformation (output of helper)
+
+@type UserTag          user tag -- arbitrary name=value pair
+       string  name    tag name
+       string  value   tag value
+
+@type ChangeACL                Management of ACL stored on bookkepping server
+       string  user_id         DN or VOMS parameter (in format VO:group)
+       int     user_id_type    type of information given in user_id (DN or VOMS)
+       _null_  -1
+       int     permission      ACL permission to change (currently only READ)
+       _null_  -1
+       int     permission_type type of permission requested ('allow', 'deny')
+       _null_  -1
+       int     operation       operation requested to perform with ACL (add, remove)
+       _null_  -1
+
+@type Notification     Management of notification service
+       notifid notifId         notification id
+       string  owner           owner
+       string  dest_host       destination host
+       port    dest_port       destination port
+       string  jobstat         job status
+
diff --git a/org.glite.lb.proxy/project/properties.xml b/org.glite.lb.proxy/project/properties.xml
new file mode 100755 (executable)
index 0000000..3bc980c
--- /dev/null
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+       Copyright (c) 2004 on behalf of the EU EGEE Project: 
+       The European Organization for Nuclear Research (CERN), 
+       Istituto Nazionale di Fisica Nucleare (INFN), Italy
+       Datamat Spa, Italy
+       Centre National de la Recherche Scientifique (CNRS), France
+       CS Systeme d'Information (CSSI), France
+       Royal Institute of Technology, Center for Parallel Computers (KTH-PDC), Sweden
+       Universiteit van Amsterdam (UvA), Netherlands
+       University of Helsinki (UH.HIP), Finland
+       University of Bergen (UiB), Norway
+       Council for the Central Laboratory of the Research Councils (CCLRC), United Kingdom
+
+       Common build properties file for the Glite LB Proxy component
+       
+       Authors: Jiri Skrabal <nykolas@ics.muni.cz>
+       
+       Revision history:
+       
+-->
+
+<project name="LB Proxy component common properties">
+
+       <!-- Include build properties to allow overwriting 
+            of properties for subsystem                    -->
+       <property file="build.properties" />    
+
+       <!-- ======================================================
+          Define corresponding subsystem properties
+                ====================================================== -->
+
+       <!-- Subsystem name -->
+       <property name="subsystem.name" value="${lb.subsystem.name}"/>
+               
+       <!-- Subsystem prefix -->
+       <property name="subsystem.prefix" value="${lb.subsystem.prefix}"/>
+
+       <!-- ======================================================
+          Define component properties
+                ====================================================== -->
+                               
+       <!-- Component name prefix -->
+       <property name="component.prefix" value="proxy" />
+                       
+       <!-- ======================================================
+          Define general component properties
+                ====================================================== -->
+       
+       <import file="${component.general.properties.file}" />
+                                               
+       <!-- ======================================================
+                Define extra properties here ...
+                ====================================================== -->
+                
+                                                               
+</project>
diff --git a/org.glite.lb.proxy/project/status.T b/org.glite.lb.proxy/project/status.T
new file mode 100644 (file)
index 0000000..10071ac
--- /dev/null
@@ -0,0 +1,77 @@
+@type _common_
+jobid  jobId           Id of the job
+string owner           Job owner
+_index_
+
+int    jobtype         Type of job
+       _null_  -1
+       _code_ SIMPLE   simple job
+       _code_ DAG      composite job
+jobid  parent_job      parent job of subjob
+
+string seed            string used for generation of subjob IDs
+int    children_num    number of subjobs
+strlist        children        list of subjob IDs
+       _special_       XMLstructured
+intlist        children_hist   summary (histogram) of children job states
+       _special_       XMLstructured
+stslist children_states full status information of the children
+       _special_       XMLstructured
+
+string         condorId        Id within Condor-G
+string globusId        Globus allocated Id
+string localId         Id within LRMS
+
+string jdl             User submitted job description
+string matched_jdl     Full job description after matchmaking
+string destination     ID of CE where the job is being sent
+_index_
+string condor_jdl      ClassAd passed to Condor-G for last job execution
+string rsl             Job RSL sent to Globus
+
+string reason          Reason of being in this status, if any
+
+string location        Where the job is being processed
+_index_
+string ce_node         Worker node where the job is executed
+string network_server  Network server handling the job
+
+bool   subjob_failed   Subjob failed (the parent job will fail too)
+int    done_code               Return code
+       _null_  -1
+       _code_  OK              Finished correctly
+       _code_  FAILED          Execution failed
+       _code_  CANCELLED       Cancelled by user
+int    exit_code               Unix exit code
+bool   resubmitted     The job was resubmitted
+
+bool   cancelling      Cancellation request in progress
+string cancelReason    Reason of cancel
+
+int    cpuTime         Consumed CPU time
+       _null_  -1
+
+taglist        user_tags       List of pairs (user_tag, user_value)
+       _special_       XMLstructured
+
+timeval        stateEnterTime  When entered this status
+timeval        lastUpdateTime  Last known event of the job
+
+intlist        stateEnterTimes When all previous states were entered
+       _special_       XMLstructured
+
+bool   expectUpdate    Some logged information has not arrived yet
+string expectFrom      Sources of the missing information
+string acl             ACL of the job
+
+@type Submitted                entered by the user to the User Interface or registered by Job Partitioner
+@type Waiting          Accepted by WMS, waiting for resource allocation
+@type Ready            Matching resources found
+@type Scheduled                Accepted by LRMS queue
+@type Running          Executable is running
+@type Done             Execution finished, output is available
+@type Cleared          Output transfered back to user and freed
+@type Aborted          Aborted by system (at any stage)
+@type Cancelled                Cancelled by user
+@type Unknown          Status cannot be determined
+@type Purged           Job has been purged from bookkeeping server (for LB->RGMA interface)
diff --git a/org.glite.lb.proxy/project/tar_exclude b/org.glite.lb.proxy/project/tar_exclude
new file mode 100644 (file)
index 0000000..b3133e4
--- /dev/null
@@ -0,0 +1,10 @@
+tar_exclude
+CVS
+build.xml
+build
+build.properties
+properties.xml
+configure-options.xml
+.cvsignore
+.project
+.cdtproject
diff --git a/org.glite.lb.proxy/project/types.T b/org.glite.lb.proxy/project/types.T
new file mode 100644 (file)
index 0000000..ccabc74
--- /dev/null
@@ -0,0 +1,108 @@
+%types = (
+       C=>{
+               bool=>'"int"',
+               string=>'"char *"',
+               strlist=>'"char **"',
+               intlist=>'"int *"',
+               taglist=>'"edg_wll_TagValue *"',
+               stslist=>'"struct _edg_wll_JobStat *"',
+               timeval=>'"struct timeval"',
+               jobid=>'"edg_wlc_JobId"',
+               notifid=>'"edg_wll_NotifId"',
+               logsrc=>'"edg_wll_Source"',
+               port=>'"uint16_t"',
+#              level=>'"enum edg_wll_Level"',
+               int=>'"int"'
+       },
+       'C++'=>{
+               string=>'"std::string"',
+               timeval=>'"struct timeval"',
+               jobid=>'"edg::workload::common::jobid::JobId"',
+               bool=>'"int"',
+                intlist=>'"std::vector<int>"',
+                strlist=>'"std::vector<std::string>"',
+                taglist=>'"std::vector<std::pair<std::string>>"',
+               stslist=>'"std::vector<JobStatus>"',
+               logsrc=>'"int"',
+               port=>'"int"',
+               int=>'"int"'
+       }
+);
+
+%toString = (
+       C=>{
+               int=>'qq{asprintf(&$dst,"%d",$src);}',
+               port=>'qq{asprintf(&$dst,"%d",(int) $src);}',
+               bool=>'qq{asprintf(&$dst,"%d",$src);}',
+               string=>'qq{$dst = $src?strdup($src):NULL;}',
+               timeval=>'qq{edg_wll_ULMTimevalToDate(($src).tv_sec,($src).tv_usec,$dst);}',
+               jobid=>'qq{$dst = edg_wlc_JobIdUnparse($src);}',
+               notifid=>'qq{$dst = edg_wll_NotifIdUnparse($src);}',
+#              level=>'qq{$dst = edg_wll_LevelToString($src);}',
+               logsrc=>'qq{$dst = edg_wll_SourceToString($src);}',
+#      strlist, intlist, stslist are used only in consumer API, they don't need toString method
+       }
+);
+
+%ULMasString = (
+       logsrc=>1
+);
+
+%fromString = (
+       C=>{
+               int=>'qq{$dst = atoi($src);}',
+               port=>'qq{$dst = (uint16_t) atoi($src);}',
+               bool=>'qq{$dst = atoi($src);}',
+               string=>'qq{$dst = strdup($src);}',
+               timeval=>'qq{edg_wll_ULMDateToTimeval($src,&$dst);}',
+               jobid=>'qq{edg_wlc_JobIdParse($src,&$dst);}',
+               notifid=>'qq{edg_wll_NotifIdParse($src,&$dst);}',
+#              level=>'qq{$dst = edg_wll_StringToLevel($src);}',
+               logsrc=>'qq{$dst = edg_wll_StringToSource($src);}',
+#      strlist, intlist, stslist are used only in consumer API, they don't need fromString method
+       }
+);
+
+%DefaultNullValue = (
+       int=>0,
+       port=>0,
+#      level=>'EDG_WLL_LEVEL_UNDEFINED',
+       bool=>0,
+       string=>'NULL',
+       jobid=>'NULL',
+       notifid=>'NULL',
+       logsrc=>'EDG_WLL_SOURCE_NONE',
+       timeval=>'null_timeval',
+       strlist=>'NULL',
+       intlist=>'NULL',
+       taglist=>'NULL',
+       stslist=>'NULL',
+);
+
+%compare = (
+       C=>{
+               int=>'"($a == $b)"',
+               port=>'"($a == $b)"',
+#              level=>'"($a == $b)"',
+               bool=>'"(($a || !$b) && ($b || !$a))"',
+               string=>'"(($a) == NULL && ($b) == NULL) || (($a)&&($b)&& !strcmp($a,$b))"',
+               jobid=>'"(($a) == NULL && ($b) == NULL) || (($a)&&($b)&& !strcmp(edg_wlc_JobIdUnparse($a),edg_wlc_JobIdUnparse($b)))"',
+               notifid=>'"($a) == ($b)"',
+               logsrc=>'"($a) == ($b)"',
+               timeval=>'"($a).tv_sec == ($b).tv_sec && ($a).tv_usec == ($b).tv_usec"',
+       }
+);
+
+%toFormatString = (
+       C=>{
+               int=>'"%d"',
+               port=>'"%d"',
+               bool=>'"%d"',
+#              level=>'"%s"',
+               string=>'"%|Us"',
+               jobid=>'"%s"',
+               notifid=>'"%s"',
+               logsrc=>'"%s"',
+               timeval=>'"%s"',
+       }
+);
diff --git a/org.glite.lb.proxy/project/version.properties b/org.glite.lb.proxy/project/version.properties
new file mode 100644 (file)
index 0000000..acd8cb9
--- /dev/null
@@ -0,0 +1,4 @@
+#Wed Jan 12 04:18:30 CET 2005
+module.version=1.1.0
+module.build=0
+module.age=0
diff --git a/org.glite.lb.proxy/src/lbproxy.c b/org.glite.lb.proxy/src/lbproxy.c
new file mode 100644 (file)
index 0000000..1d305de
--- /dev/null
@@ -0,0 +1,543 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <linux/limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <sys/un.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <errno.h>
+#include <netdb.h>
+#include <limits.h>
+#include <syslog.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <ares.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
+
+#include "glite/lb/srvbones.h"
+#include "glite/lb/context.h"
+#include "glite/lb/context-int.h"
+
+extern int edg_wll_DBCheckVersion(edg_wll_Context);
+extern edg_wll_ErrorCode edg_wll_Open(edg_wll_Context ctx, char *cs);
+extern edg_wll_ErrorCode edg_wll_Close(edg_wll_Context);
+extern int edg_wll_StoreProtoProxy(edg_wll_Context ctx);
+extern int edg_wll_ServerHTTP(edg_wll_Context ctx);
+
+extern char *lbproxy_ilog_socket_path;
+extern char *lbproxy_ilog_file_prefix;
+
+
+#define DEFAULTCS                      "lbserver/@localhost:lbserver20"
+/*
+#define DEFAULTCS                      "lbserver/@localhost:lbproxy"
+*/
+
+#define CON_QUEUE                      20      /* accept() */
+#define SLAVE_OVERLOAD         10      /* queue items per slave */
+#define CLNT_TIMEOUT           10      /* keep idle connection that many seconds */
+#define TOTAL_CLNT_TIMEOUT     60      /* one client may ask one slave multiple times */
+                                       /* but only limited time to avoid DoS attacks */
+#define CLNT_REJECT_TIMEOUT    100000  /* time limit for client rejection in !usec! */
+#define DNS_TIMEOUT            5       /* how long wait for DNS lookup */
+#define SLAVE_CONNS_MAX                500     /* commit suicide after that many connections */
+#define MASTER_TIMEOUT         30      /* maximal time of one-round of master network communication */
+#define SLAVE_TIMEOUT          30      /* maximal time of one-round of slave network communication */
+
+/* file to store pid and generate semaphores key
+ */
+#ifndef GLITE_LBPROXY_PIDFILE
+#define GLITE_LBPROXY_PIDFILE          "/var/run/glite-lbproxy.pid"
+#endif
+
+#ifndef GLITE_LBPROXY_SOCK_PREFIX
+#define GLITE_LBPROXY_SOCK_PREFIX      "/tmp/lb_proxy_"
+#endif
+
+#ifndef dprintf
+#define dprintf(x)                     { if (debug) printf x; }
+#endif
+
+#define sizofa(a)                      (sizeof(a)/sizeof((a)[0]))
+
+
+int                                            debug  = 0;
+static const int               one = 1;
+static char                       *dbstring = NULL;
+static char                            sock_store[PATH_MAX],
+                                               sock_serve[PATH_MAX];
+static int                             slaves = 10,
+                                               semaphores = -1,
+                                               semset;
+
+
+static struct option opts[] = {
+       {"port",                1, NULL,        'p'},
+       {"debug",               0, NULL,        'd'},
+       {"mysql",               1, NULL,        'm'},
+       {"slaves",              1, NULL,        's'},
+       {"semaphores",          1, NULL,        'l'},
+       {"pidfile",             1, NULL,        'i'},
+       {"proxy-il-sock",       1, NULL,        'X'},
+       {"proxy-il-fprefix",    1, NULL,        'Y'},
+       {NULL,0,NULL,0}
+};
+
+static const char *get_opt_string = "p:dm:s:l:i:X:Y:";
+
+static void usage(char *me) 
+{
+       fprintf(stderr,"usage: %s [option]\n"
+               "\t-p, --sock\t path-name to the local socket\n"
+               "\t-m, --mysql\t database connect string\n"
+               "\t-d, --debug\t don't run as daemon, additional diagnostics\n"
+               "\t-s, --slaves\t number of slave servers to fork\n"
+               "\t-l, --semaphores number of semaphores (job locks) to use\n"
+               "\t-i, --pidfile\t file to store master pid\n"
+               "\t--proxy-il-sock\t socket to send events to\n"
+               "\t--proxy-il-fprefix\t file prefix for events\n"
+       ,me);
+}
+
+static void wait_for_open(edg_wll_Context,const char *);
+
+
+/*
+ *     SERVER BONES structures and handlers
+ */
+int clnt_data_init(void **);
+
+       /*
+        *      Serve & Store handlers
+        */
+int clnt_reject(int);
+int handle_conn(int, struct timeval, void *);
+int accept_serve(int, void *);
+int accept_store(int, void *);
+int clnt_disconnect(int, void *);
+
+#define SRV_SERVE              0
+#define SRV_STORE              1
+static struct glite_srvbones_service service_table[] = {
+       { "serve",      -1, handle_conn, accept_serve, clnt_reject, clnt_disconnect },
+       { "store",      -1, handle_conn, accept_store, clnt_reject, clnt_disconnect },
+};
+
+struct clnt_data_t {
+       edg_wll_Context                 ctx;
+       void                               *mysql;
+};
+
+
+
+int main(int argc, char *argv[])
+{
+       int                                     i;
+       struct sockaddr_un      a;
+       int                                     opt;
+       char                            pidfile[PATH_MAX] = GLITE_LBPROXY_PIDFILE,
+                                               socket_path_prefix[PATH_MAX] = GLITE_LBPROXY_SOCK_PREFIX,
+                                          *name;
+       FILE                       *fpid;
+       key_t                           semkey;
+       edg_wll_Context         ctx;
+       struct timeval          to;
+
+
+
+       name = strrchr(argv[0],'/');
+       if (name) name++; else name = argv[0];
+
+       if (geteuid()) snprintf(pidfile,sizeof pidfile,"%s/glite_lb_proxy.pid", getenv("HOME"));
+
+       while ((opt = getopt_long(argc, argv, get_opt_string, opts, NULL)) != EOF) switch (opt) {
+               case 'p': strcpy(socket_path_prefix, optarg); break;
+               case 'd': debug = 1; break;
+               case 'm': dbstring = optarg; break;
+               case 's': slaves = atoi(optarg); break;
+               case 'l': semaphores = atoi(optarg); break;
+               case 'X': lbproxy_ilog_socket_path = strdup(optarg); break;
+               case 'Y': lbproxy_ilog_file_prefix = strdup(optarg); break;
+               case 'i': strcpy(pidfile, optarg); break;
+               case '?': usage(name); return 1;
+       }
+
+       if ( optind < argc ) { usage(name); return 1; }
+
+       setlinebuf(stdout);
+       setlinebuf(stderr);
+
+       fpid = fopen(pidfile,"r");
+       if ( fpid ) {
+               int     opid = -1;
+
+               if ( fscanf(fpid,"%d",&opid) == 1 ) {
+                       if ( !kill(opid,0) ) {
+                               fprintf(stderr,"%s: another instance running, pid = %d\n",argv[0],opid);
+                               return 1;
+                       }
+                       else if (errno != ESRCH) { perror("kill()"); return 1; }
+               }
+               fclose(fpid);
+       } else if (errno != ENOENT) { perror(pidfile); return 1; }
+
+       fpid = fopen(pidfile, "w");
+       if ( !fpid ) { perror(pidfile); return 1; }
+       fprintf(fpid, "%d", getpid());
+       fclose(fpid);
+
+       semkey = ftok(pidfile,0);
+
+       if ( semaphores == -1 ) semaphores = slaves;
+       semset = semget(semkey, 0, 0);
+       if ( semset >= 0 ) semctl(semset, 0, IPC_RMID);
+       semset = semget(semkey, semaphores, IPC_CREAT | 0600);
+       if ( semset < 0 ) { perror("semget()"); return 1; }
+       dprintf(("Using %d semaphores, set id %d\n", semaphores, semset));
+       for ( i = 0; i < semaphores; i++ ) {
+               struct sembuf   s;
+
+               s.sem_num = i; s.sem_op = 1; s.sem_flg = 0;
+               if (semop(semset,&s,1) == -1) { perror("semop()"); return 1; }
+       }
+
+       service_table[SRV_SERVE].conn = socket(PF_UNIX, SOCK_STREAM, 0);
+       if ( service_table[SRV_SERVE].conn < 0 ) { perror("socket()"); return 1; }
+       memset(&a, 0, sizeof(a));
+       a.sun_family = AF_UNIX;
+       sprintf(sock_serve, "%s%s", socket_path_prefix, "serve.sock");
+       strcpy(a.sun_path, sock_serve);
+
+       if( connect(service_table[SRV_SERVE].conn, (struct sockaddr *)&a, sizeof(a.sun_path)) < 0) {
+               if( errno == ECONNREFUSED ) {
+                       dprintf(("removing stale input socket %s\n", sock_serve));
+                       unlink(sock_serve);
+               }
+       } else { perror("another instance of lb-proxy is running"); return 1; }
+
+       if ( bind(service_table[SRV_SERVE].conn, (struct sockaddr *) &a, sizeof(a)) < 0 ) {
+               char    buf[100];
+
+               snprintf(buf, sizeof(buf), "bind(%s)", sock_serve);
+               perror(buf);
+               return 1;
+       }
+
+       if ( listen(service_table[SRV_SERVE].conn, CON_QUEUE) ) { perror("listen()"); return 1; }
+
+       service_table[SRV_STORE].conn = socket(PF_UNIX, SOCK_STREAM, 0);
+       if ( service_table[SRV_STORE].conn < 0 ) { perror("socket()"); return 1; }
+       memset(&a, 0, sizeof(a));
+       a.sun_family = AF_UNIX;
+       sprintf(sock_store, "%s%s", socket_path_prefix, "store.sock");
+       strcpy(a.sun_path, sock_store);
+
+       if( connect(service_table[SRV_STORE].conn, (struct sockaddr *)&a, sizeof(a.sun_path)) < 0) {
+               if( errno == ECONNREFUSED ) {
+                       dprintf(("removing stale input socket %s\n", sock_store));
+                       unlink(sock_store);
+               }
+       } else { perror("another instance of lb-proxy is running"); return 1; }
+
+       if ( bind(service_table[SRV_STORE].conn, (struct sockaddr *) &a, sizeof(a))) {
+               char    buf[100];
+
+               snprintf(buf, sizeof(buf), "bind(%s)", sock_store);
+               perror(buf);
+               return 1;
+       }
+       if ( listen(service_table[SRV_STORE].conn, CON_QUEUE) ) { perror("listen()"); return 1; }
+
+       dprintf(("Listening at %s, %s ...\n", sock_store, sock_serve));
+
+       if (!dbstring) dbstring = getenv("LBPROXYDB");
+       if (!dbstring) dbstring = DEFAULTCS;
+
+
+       /* Just check the database and let it be. The slaves do the job. */
+       /* XXX: InitContextProxy() !!!
+        * edg_wll_InitContext(&ctx) causes segfault
+        */
+       if ( !(ctx = (edg_wll_Context) malloc(sizeof(*ctx))) ) {
+               perror("InitContext()");
+               return -1;
+       }
+       memset(ctx, 0, sizeof(*ctx));
+       wait_for_open(ctx, dbstring);
+       if (edg_wll_DBCheckVersion(ctx)) {
+               char    *et,*ed;
+               edg_wll_Error(ctx,&et,&ed);
+
+               fprintf(stderr,"%s: open database: %s (%s)\n",argv[0],et,ed);
+               return 1;
+       }
+       edg_wll_Close(ctx);
+       edg_wll_FreeContext(ctx);
+
+       if ( !debug ) {
+               if ( daemon(1,0) == -1 ) { perror("deamon()"); exit(1); }
+
+               fpid = fopen(pidfile,"w");
+               if ( !fpid ) { perror(pidfile); return 1; }
+               fprintf(fpid, "%d", getpid());
+               fclose(fpid);
+               openlog(name, LOG_PID, LOG_DAEMON);
+       } else { setpgid(0, getpid()); }
+
+
+       glite_srvbones_set_param(GLITE_SBPARAM_SLAVES_CT, slaves);
+       glite_srvbones_set_param(GLITE_SBPARAM_SLAVE_OVERLOAD, SLAVE_OVERLOAD);
+       glite_srvbones_set_param(GLITE_SBPARAM_SLAVE_CONNS_MAX, SLAVE_CONNS_MAX);
+       to = (struct timeval){CLNT_TIMEOUT, 0};
+       glite_srvbones_set_param(GLITE_SBPARAM_CLNT_TIMEOUT, &to);
+       to = (struct timeval){TOTAL_CLNT_TIMEOUT, 0};
+       glite_srvbones_set_param(GLITE_SBPARAM_TOTAL_CLNT_TIMEOUT, &to);
+
+       glite_srvbones_run(clnt_data_init, service_table, sizofa(service_table), debug);
+
+
+       semctl(semset, 0, IPC_RMID, 0);
+       unlink(pidfile);
+       for ( i = 0; i < sizofa(service_table); i++ )
+               if ( service_table[i].conn >= 0 ) close(service_table[i].conn);
+       unlink(sock_serve);
+       unlink(sock_store);
+
+
+       return 0;
+}
+
+
+int clnt_data_init(void **data)
+{
+       edg_wll_Context                 ctx;
+       struct clnt_data_t         *cdata;
+
+
+       if ( !(cdata = calloc(1, sizeof(*cdata))) )
+               return -1;
+
+       if ( !(ctx = (edg_wll_Context) malloc(sizeof(*ctx))) ) { free(cdata); return -1; }
+       memset(ctx, 0, sizeof(*ctx));
+
+       dprintf(("[%d] opening database ...\n", getpid()));
+       wait_for_open(ctx, dbstring);
+       cdata->mysql = ctx->mysql;
+       edg_wll_FreeContext(ctx);
+
+       *data = cdata;
+       return 0;
+}
+
+       
+int handle_conn(int conn, struct timeval client_start, void *data)
+{
+       struct clnt_data_t *cdata = (struct clnt_data_t *)data;
+       edg_wll_Context         ctx;
+       struct timeval          total_to = { TOTAL_CLNT_TIMEOUT,0 };
+
+
+       if ( !(ctx = (edg_wll_Context) calloc(1, sizeof(*ctx))) ) {
+               fprintf(stderr, "Couldn't create context");
+               return -1;
+       }
+       cdata->ctx = ctx;
+
+       /* Shared structures (pointers)
+        */
+       ctx->mysql = cdata->mysql;
+       
+       /*      set globals
+        */
+       ctx->allowAnonymous = 1;
+       ctx->isProxy = 1;
+       ctx->noAuth = 1;
+       ctx->noIndex = 1;
+       ctx->semset = semset;
+       ctx->semaphores = semaphores;
+
+       ctx->p_tmp_timeout.tv_sec = SLAVE_TIMEOUT;
+       ctx->p_tmp_timeout.tv_usec = 0;
+       if ( total_to.tv_sec < ctx->p_tmp_timeout.tv_sec ) {
+               ctx->p_tmp_timeout.tv_sec = total_to.tv_sec;
+               ctx->p_tmp_timeout.tv_usec = total_to.tv_usec;
+       }
+       
+       ctx->connProxy = (edg_wll_ConnProxy *) calloc(1, sizeof(edg_wll_ConnProxy));
+       if ( !ctx->connProxy ) {
+               perror("calloc");
+               edg_wll_FreeContext(ctx);
+
+               return -1;
+       }
+
+       if ( edg_wll_plain_accept(conn, &ctx->connProxy->conn) ) {
+               perror("accept");
+               edg_wll_FreeContext(ctx);
+
+               return -1;
+       } 
+
+
+       return 0;
+}
+
+
+int accept_store(int conn, void *cdata)
+{
+       edg_wll_Context         ctx = ((struct clnt_data_t *) cdata)->ctx;
+
+       if ( edg_wll_StoreProtoProxy(ctx) ) { 
+               char    *errt, *errd;
+
+               errt = errd = NULL;
+               switch ( edg_wll_Error(ctx, &errt, &errd) ) {
+               case ETIMEDOUT:
+               case EPIPE:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*      fallthrough
+                        */
+               case ENOTCONN:
+                       edg_wll_FreeContext(ctx);
+                       ctx = NULL;
+                       free(errt); free(errd);
+                       dprintf(("[%d] Connection closed\n", getpid()));
+                       return 1;
+                       break;
+
+               case ENOENT:
+               case EINVAL:
+               case EPERM:
+               case EEXIST:
+               case EDG_WLL_ERROR_NOINDEX:
+               case E2BIG:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if ( !debug ) syslog(LOG_ERR, "%s (%s)", errt, errd);
+                       break;
+                       
+               default:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if ( !debug ) syslog(LOG_CRIT, "%s (%s)", errt, errd);
+                       return -1;
+               } 
+               free(errt); free(errd);
+       }
+
+       return 0;
+}
+
+int accept_serve(int conn, void *cdata)
+{
+       edg_wll_Context         ctx = ((struct clnt_data_t *) cdata)->ctx;
+
+       /*
+        *      serve the request
+        */
+       if ( edg_wll_ServerHTTP(ctx) ) { 
+               char    *errt, *errd;
+
+               
+               errt = errd = NULL;
+               switch ( edg_wll_Error(ctx, &errt, &errd) ) {
+               case ETIMEDOUT:
+               case EPIPE:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*      fallthrough
+                        */
+               case ENOTCONN:
+                       edg_wll_FreeContext(ctx);
+                       ctx = NULL;
+                       free(errt); free(errd);
+                       dprintf(("[%d] Connection closed\n", getpid()));
+                       /*
+                        *      "recoverable" error - return (>0)
+                        */
+                       return 1;
+                       break;
+
+               case ENOENT:
+               case EINVAL:
+               case EPERM:
+               case EEXIST:
+               case EDG_WLL_ERROR_NOINDEX:
+               case E2BIG:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if ( !debug ) syslog(LOG_ERR,"%s (%s)", errt, errd);
+                       /*
+                        *      no action for non-fatal errors
+                        */
+                       break;
+                       
+               default:
+                       dprintf(("[%d] %s (%s)\n", getpid(), errt, errd));
+                       if (!debug) syslog(LOG_CRIT,"%s (%s)",errt,errd);
+                       /*
+                        *      unknown error - do rather return (<0) (slave will be killed)
+                        */
+                       return -1;
+               } 
+               free(errt); free(errd);
+       }
+
+       return 0;
+}
+
+
+int clnt_disconnect(int conn, void *cdata)
+{
+       edg_wll_Context         ctx = ((struct clnt_data_t *) cdata)->ctx;
+
+       edg_wll_FreeContext(ctx);
+
+       return 0;
+}
+
+int clnt_reject(int conn)
+{
+       return 0;
+}
+
+static void wait_for_open(edg_wll_Context ctx, const char *dbstring)
+{
+       char    *dbfail_string1, *dbfail_string2;
+
+       dbfail_string1 = dbfail_string2 = NULL;
+
+       while (edg_wll_Open(ctx, (char *) dbstring)) {
+               char    *errt,*errd;
+
+               if (dbfail_string1) free(dbfail_string1);
+               edg_wll_Error(ctx,&errt,&errd);
+               asprintf(&dbfail_string1,"%s (%s)\n",errt,errd);
+               if (dbfail_string1 != NULL) {
+                       if (dbfail_string2 == NULL || strcmp(dbfail_string1,dbfail_string2)) {
+                               if (dbfail_string2) free(dbfail_string2);
+                               dbfail_string2 = dbfail_string1;
+                               dbfail_string1 = NULL;
+                               dprintf(("[%d]: %s\nStill trying ...\n",getpid(),dbfail_string2));
+                               if (!debug) syslog(LOG_ERR,dbfail_string2);
+                       }
+               }
+               sleep(5);
+       }
+
+       if (dbfail_string1) free(dbfail_string1);
+       if (dbfail_string2 != NULL) {
+               free(dbfail_string2);
+               dprintf(("[%d]: DB connection established\n",getpid()));
+               if (!debug) syslog(LOG_INFO,"DB connection established\n");
+       }
+}