X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-server;h=1dd69157831df62552ae5277a4f56412f38b6b34;hb=7067bdf5cb4d4f7fc5a303c9005c183baeccff67;hp=807f86a85ec7d2caf523e43ddc82405918a060d0;hpb=5e09e958689ad06b082821299940196c232eea29;p=gosa.git diff --git a/gosa-si/gosa-si-server b/gosa-si/gosa-si-server index 807f86a85..1dd691578 100755 --- a/gosa-si/gosa-si-server +++ b/gosa-si/gosa-si-server @@ -9,8 +9,7 @@ # # OPTIONS: --- # REQUIREMENTS: libconfig-inifiles-perl libcrypt-rijndael-perl libxml-simple-perl -# libipc-shareable-perl libdata-dumper-simple-perl -# libdbd-sqlite3-perl libnet-ldap-perl +# libdata-dumper-simple-perl libdbd-sqlite3-perl libnet-ldap-perl # BUGS: --- # NOTES: # AUTHOR: (Andreas Rettenberger), @@ -30,6 +29,9 @@ use Time::HiRes qw( gettimeofday ); use Fcntl; use IO::Socket::INET; +use IO::Handle; +use IO::Select; +use Symbol qw(qualify_to_ref); use Crypt::Rijndael; use MIME::Base64; use Digest::MD5 qw(md5 md5_hex md5_base64); @@ -38,10 +40,9 @@ use Data::Dumper; use Sys::Syslog qw( :DEFAULT setlogsock); use Cwd; use File::Spec; -use IPC::Shareable qw( :lock); -IPC::Shareable->clean_up_all; use GOSA::GosaSupportDaemon; use GOSA::DBsqlite; +use threads; my $modules_path = "/usr/lib/gosa-si/modules"; use lib "/usr/lib/gosa-si/modules"; @@ -113,7 +114,7 @@ our $known_clients_db; "bus" => {"bus_activ" => [\$bus_activ, "on"], "bus_passwd" => [\$bus_passwd, ""], - "bus_ip" => [\$bus_ip, ""], + "bus_ip" => [\$bus_ip, "0.0.0.0"], "bus_port" => [\$bus_port, "20080"], }, "server" => @@ -129,7 +130,7 @@ our $known_clients_db; }, "gosa" => {"gosa_activ" => [\$gosa_activ, "on"], - "gosa_ip" => [\$gosa_ip, ""], + "gosa_ip" => [\$gosa_ip, "0.0.0.0"], "gosa_port" => [\$gosa_port, "20082"], "gosa_passwd" => [\$gosa_passwd, "none"], }, @@ -170,7 +171,7 @@ sub read_configfile { if( -r $cfg_file ) { $cfg = Config::IniFiles->new( -file => $cfg_file ); } else { - print STDERR "Couldn't read config file!"; + print STDERR "Couldn't read config file!\n"; } } else { $cfg = Config::IniFiles->new() ; @@ -192,7 +193,7 @@ sub read_configfile { # RETURNS: nothing # DESCRIPTION: function for logging #=============================================================================== -sub daemon_log { +sub daemon_log : locked { # log into log_file my( $msg, $level ) = @_; if(not defined $msg) { return } @@ -204,11 +205,26 @@ sub daemon_log { return } chomp($msg); if($level <= $verbose){ - print LOG_HANDLE "$level $msg\n"; - if($foreground) { print $msg."\n" } + my ($seconds, $minutes, $hours, $monthday, $month, + $year, $weekday, $yearday, $sommertime) = localtime(time); + $hours = $hours < 10 ? $hours = "0".$hours : $hours; + $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes; + $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds; + my @monthnames = ("Jan", "Feb", "Mar", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); + $month = $monthnames[$month]; + $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; + $year+=1900; + my $name = $0; + $name =~ s/\.\///; + + my $log_msg = "$month $monthday $hours:$minutes:$seconds $name $msg\n"; + print LOG_HANDLE $log_msg; + if( $foreground ) { + print STDERR $log_msg; + } } + close( LOG_HANDLE ); } -# close( LOG_HANDLE ); #log into syslog # my ($msg, $level, $facility) = @_; # if(not defined $msg) {return} @@ -316,18 +332,16 @@ sub import_modules { } eval { require $file; }; if ($@) { - daemon_log("ERROR: gosa-sd could not load module $file", 1); + daemon_log("ERROR: gosa-si-server could not load module $file", 1); daemon_log("$@", 5); - next; - } - my $mod_name = $1; - #my $module_tag_hash = eval( $mod_name.'::get_module_tags()' ); - - my $info = eval($mod_name.'::get_module_info()'); - my ($input_address, $input_key, $input, $input_active, $input_type) = @{$info}; - $known_modules->{$mod_name} = $info; + } else { + my $mod_name = $1; + my $info = eval($mod_name.'::get_module_info()'); + my ($input_address, $input_key, $input, $input_active, $input_type) = @{$info}; + $known_modules->{$mod_name} = $info; - daemon_log("module $mod_name loaded", 1); + daemon_log("module $mod_name loaded", 1); + } } # for debugging @@ -347,23 +361,8 @@ sub import_modules { #=============================================================================== sub sig_int_handler { my ($signal) = @_; - if($server){ - close($server); - daemon_log("daemon server closed", 1); - } - if( -p $arp_fifo_path ) { - close $arp_fifo ; - unlink($arp_fifo_path) ; - daemon_log("ARP_FIFO closed", 1) ; - } - if($gosa_server){ - close($gosa_server); - daemon_log("gosa server closed", 1); - } - - print STDERR "$signal\n"; - + daemon_log("shutting down gosa-si-server", 1); exit(1); } $SIG{INT} = \&sig_int_handler; @@ -481,26 +480,22 @@ sub get_processing_child { my $answer; my %act_modules = %$known_modules; while( my ($module, $info) = each(%act_modules)) { - &daemon_log("##########", 5); my $tmp = &{ $module."::process_incoming_msg" }($msg); if (defined $tmp) { $answer = $tmp; } - &daemon_log("##########", 5); } - - #&print_known_daemons(); - #&print_known_clients(); - daemon_log("processing of msg finished", 5); if (defined $answer) { print $PARENT_wr $answer."\n"; - daemon_log("with answer: $answer", 5); - daemon_log(" ", 5); + print $PARENT_wr "ENDMESSAGE\n"; + my $len_answer = length $answer; + daemon_log("with answer: length of answer: $len_answer", 7); + daemon_log("\n$answer", 7); } else { print $PARENT_wr "done"."\n"; - daemon_log(" ", 5); + print $PARENT_wr "ENDMESSAGE\n"; } redo; } @@ -758,142 +753,42 @@ sub create_known_client { return; } - -#=== FUNCTION ================================================================ -# NAME: add_content2known_clients -# PARAMETERS: hostname - string - ip address and port of host (required) -# status - string - (optional) -# passwd - string - (optional) -# mac_address - string - (optional) -# events - string - event of client, executable skripts -# under /etc/gosac/events -# RETURNS: nothing -# DESCRIPTION: nome est omen and updates each time the timestamp of hostname -#=============================================================================== -#sub update_known_clients { -# my $arg = { -# hostname => undef, status => undef, hostkey => undef, -# macaddress => undef, events => undef, timestamp=>undef, -# @_ }; -# my $hostname = $arg->{hostname}; -# my $status = $arg->{status}; -# my $hostkey = $arg->{hostkey}; -# my $macaddress = $arg->{macaddress}; -# my $events = $arg->{events}; -# my $timestamp = $arg->{timestamp}; +#sub sysreadline(*;$) { +# my ($hd, $timeout) = @_; # -# if (not defined $hostname) { -# daemon_log("ERROR: function add_content2known_clients is not invoked with requiered parameter 'hostname'", 1); -# return; -# } +# $hd = qualify_to_ref($hd, caller()); +# my $infinitely_patient = (@_ == 1 || $timeout < 0); +# my $start_time = time(); +# my $selector = IO::Select->new(); +# $selector->add($hd); +# my $line = ""; # -# my $change_entry = { table=>'known_clients', -# where=>'hostname', -# timestamp=>&get_time, -# }; -# -# -# if (defined $status) { -# $change_entry->{status} = $status; -# } -# if (defined $hostkey) { -# $change_entry->{hostkey} = $hostkey; -# } -# if (defined $macaddress) { -# $change_entry->{macaddress} = $macaddress; -# } -# if (defined $events) { -# $change_entry->{events} = $events; -# } -# -# $known_clients->change_dbentry($change_entry); -# return; -#} - - -#=== FUNCTION ================================================================ -# NAME: -# PARAMETERS: -# RETURNS: -# DESCRIPTION: -#=============================================================================== -#sub clean_up_known_clients { -# my ($address) = @_ ; -# -# if (not exists $known_clients->{$address}) { -# daemon_log("cannot prune known_clients from $address, client not known", 5); -# return; -# } -# -# delete $known_clients->{$address}; -# -# # send bus a msg that address was deleted from known_clients -# my $out_hash = &create_xml_hash('delete_client', $server_address, $bus_address, $address); -# &send_msg_hash2bus($out_hash); -# -# daemon_log("client $address deleted from known_clients because of multiple down time", 3); -# return; -#} - - -#=== FUNCTION ================================================================ -# NAME: update_known_clients -# PARAMETERS: hostname - string - ip address and port of host (required) -# status - string - (optional) -# passwd - string - (optional) -# client - string - ip address and port of client (optional) -# RETURNS: nothing -# DESCRIPTION: nome est omen and updates each time the timestamp of hostname -#=============================================================================== -#sub update_known_clients { -# my $arg = { -# hostname => undef, status => undef, passwd => undef, -# mac_address => undef, events => undef, -# @_ }; -# my $hostname = $arg->{hostname}; -# my $status = $arg->{status}; -# my $passwd = $arg->{passwd}; -# my $mac_address = $arg->{mac_address}; -# my $events = $arg->{events}; +#SLEEP: +# until( at_eol($line)) { +# if (not $infinitely_patient) { +# return $line if time() > ($start_time + $timeout); +# } +# next SLEEP unless $selector->can_read(1.0); +#INPUT_READY: +# while( $selector->can_read(0.0)) { +# my $was_blocking = $hd->blocking(0); +#CHAR: while (sysread($hd, my $nextbyte, 1)) { +# $line .= $nextbyte; +# last CHAR if $nextbyte eq "\n"; # -# if (not defined $hostname) { -# daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); -# return; +# } +# $hd->blocking($was_blocking); +# next SLEEP unless at_eol($line); +# last INPUT_READY; +# } # } +# return $line; +#} # -# my ($seconds, $minutes, $hours, $monthday, $month, -# $year, $weekday, $yearday, $sommertime) = localtime(time); -# $hours = $hours < 10 ? $hours = "0".$hours : $hours; -# $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes; -# $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds; -# $month+=1; -# $month = $month < 10 ? $month = "0".$month : $month; -# $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; -# $year+=1900; -# my $t = "$year$month$monthday$hours$minutes$seconds"; -# -# if (defined $status) { -# $known_clients->{$hostname}->{status} = $status; -# } -# if (defined $passwd) { -# $known_clients->{$hostname}->{passwd} = $passwd; -# } -# if (defined $mac_address) { -# $known_clients->{$hostname}->{mac_address} = $mac_address; -# } -# if (defined $events) { -# $known_clients->{$hostname}->{events} = $events; -# } -# $known_clients_db->{$hostname}->{timestamp} = $t; -# return; +#sub at_eol($) { +# $_[0] =~ /\n\z/ ; #} - - - - - - #==== MAIN = main ============================================================== # parse commandline options @@ -913,18 +808,16 @@ GetOptions("h|help" => \&usage, $SIG{CHLD} = 'IGNORE'; -# restart daemon log file -daemon_log(" ", 1); -daemon_log("$0 started!", 1); +# forward error messages to logfile +if( ! $foreground ) { + open(STDERR, '>>', $log_file); + open(STDOUT, '>>', $log_file); +} -# Just fork, if we"re not in foreground mode +# Just fork, if we are not in foreground mode if( ! $foreground ) { chdir '/' or die "Can't chdir to /: $!"; - open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; - open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!"; - open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!"; - defined($pid = fork) or die "Can't fork: $!"; - exit if $pid; + $pid = fork; setsid or die "Can't start a new session: $!"; umask 0; } else { @@ -941,8 +834,14 @@ if( 0 != $pid ) { }; } +daemon_log(" ", 1); +daemon_log("$0 started!", 1); + +# delete old DBsqlite lock files +system('rm -f /tmp/gosa_si_lock*'); + # connect to gosa-si job queue -my @job_col_names = ("timestamp", "status", "result", "headertag", "targettag", "xmlmessage", "macaddress"); +my @job_col_names = ("id", "timestamp", "status", "result", "headertag", "targettag", "xmlmessage", "macaddress"); $job_db = GOSA::DBsqlite->new($job_queue_file_name); $job_db->create_table('jobs', \@job_col_names); @@ -1070,38 +969,33 @@ while(1) { if (vec($rout, fileno $fhd, 1) ) { daemon_log("process child $pid is ready to read", 5); - - $fhd->blocking(1); - my $in_msg = <$fhd>; - $fhd->blocking(0); - my $part_in_msg; - while ($part_in_msg = <$fhd>) { - if (not defined $part_in_msg) { + + my $in_msg; + while (1) { + my $part_in_msg = <$fhd>; + if( $part_in_msg eq "ENDMESSAGE\n") { last; } $in_msg .= $part_in_msg; } chomp($in_msg); - - daemon_log("process child read: $in_msg", 5); + if (not defined $in_msg) { next; } elsif ($in_msg =~ "done") { + daemon_log("process child read: $in_msg", 7); delete $busy_child{$pid}; $free_child{$pid} = $child_hash; - + } else { + daemon_log("process child read:", 7); + daemon_log("\n$in_msg", 8); # send computed answer back to connected client my $act_client = $busy_child{$pid}{client_ref}; print $act_client $in_msg."\n"; - - #my $act_pipe = $busy_child{$pid}{pipe_rd}; delete $busy_child{$pid}; $free_child{$pid} = $child_hash; - # give the client a chance to read - sleep(2); - close ($act_client); } } } @@ -1123,7 +1017,7 @@ while(1) { while( my ($id, $hit) = each %{$res} ) { - my $jobdb_id = $hit->{ROWID}; + my $jobdb_id = $hit->{id}; my $macaddress = $hit->{macaddress}; my $job_msg_hash = &transform_msg2hash($hit->{xmlmessage}); my $out_msg_hash = $job_msg_hash; @@ -1136,7 +1030,7 @@ while(1) { &daemon_log("xml message: $hit->{xmlmessage}", 5); my $update_hash = { table=>$job_queue_table_name, update=> [ { status=>['error'], result=>["no host found for mac address"] } ], - where=> [ { ROWID=>[$jobdb_id] } ], + where=> [ { id=>[$jobdb_id] } ], }; my $res = $job_db->update_dbentry($update_hash); @@ -1163,16 +1057,13 @@ while(1) { my $error = &send_msg_hash2address($out_msg_hash, "$gosa_ip:$gosa_port", $gosa_passwd); -####################### -# TODO exchange ROWID with jobid, insert column jobid in table jobs befor - if ($error == 0) { - my $sql = "UPDATE '$job_queue_table_name' SET status='processing', targettag='$target' WHERE ROWID='$jobdb_id'"; + my $sql = "UPDATE '$job_queue_table_name' SET status='processing', targettag='$target' WHERE id='$jobdb_id'"; my $res = $job_db->exec_statement($sql); } else { my $update_hash = { table=>$job_queue_table_name, update=> [ { status=>'error' } ], - where=> [ { ROWID=>$jobdb_id } ], + where=> [ { id=>$jobdb_id } ], }; my $res = $job_db->update_dbentry($update_hash); }