--- /dev/null
+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
--- /dev/null
+# 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
--- /dev/null
+<?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&B Proxy server" />
+ <property name="build.package.description" value=" The daemon
+installed at the ??? machine.
It is responsible for accepting events from
+???, storing them in RDBMS, forwarding then to the real L&B server
and performing queries on client requests
+(job status, job log etc.).
Also includes purge utilities
+to remove (and optionally archive) inactive
data from
+the database and to change database index configuration." />
+
+</project>
--- /dev/null
+
+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
--- /dev/null
+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)
+);
--- /dev/null
+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;
--- /dev/null
+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}};
+}
--- /dev/null
+#!/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');
--- /dev/null
+<?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>
--- /dev/null
+@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
+
--- /dev/null
+<?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>
--- /dev/null
+@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)
--- /dev/null
+tar_exclude
+CVS
+build.xml
+build
+build.properties
+properties.xml
+configure-options.xml
+.cvsignore
+.project
+.cdtproject
--- /dev/null
+%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"',
+ }
+);
--- /dev/null
+#Wed Jan 12 04:18:30 CET 2005
+module.version=1.1.0
+module.build=0
+module.age=0
--- /dev/null
+#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");
+ }
+}