#!/usr/bin/perl -s use Proc::Daemon; use Proc::PID::File; use POSIX; use IO::File; use Storable; use File::Slurp qw/write_file/; $| = 1; my $fifo_path = '/var/run/sqdproc/sqd.fifo'; my $datafile = '/var/run/sqdproc/sqd.data'; my $workers; $workers = retrieve $datafile if -e $datafile; my $command = shift; unless ($command) { print "Syntax: sqd start|stop|status|create |list|drop |submit \n"; exit; } if ($command eq 'create') { my $dir = shift; die unless $dir; write_to_fifo("create $< $dir"); exit; } if ($command eq 'submit') { my $dir = shift; my $target = shift; die unless ($dir and $target); my $script = ''; while (<>) { $script .= $_; } my $worker_exists = 0; foreach (sort keys %$workers) { $worker_exists = 1 if ($workers->{$_}->{'dir'} =~ m/$dir\/?/); } if ($worker_exists) { write_file( "$dir/QUEUE/$target", {binmode => ':utf8'}, $script ); print STDERR "New job submitted as: $dir/QUEUE/$target\n"; } else { print STDERR "Worker for $dir not found\n"; } exit; } if ($command eq 'drop') { my $dir = shift; die unless $dir; my $kill = 0; foreach (sort keys %$workers) { $kill = $_ if ($workers->{$_}->{'dir'} eq $dir); } if ($kill) { # $workers->{$_}->{'daemon'}->Kill_Daemon; # XXX `sudo kill $kill`; delete $workers->{$kill}; store $workers, $datafile; print STDERR "Worker dropped.\n"; } else { print STDERR "Worker not found.\n"; } exit; } if ($command eq 'list') { print "Pid\tStatus\tDir\n"; foreach (sort keys %$workers) { print "$_\t"; ($_ eq $workers->{$_}->{'daemon'}->Status) ? print "Ok" : print "Nok"; print "\t$workers->{$_}->{'dir'}\n"; } exit; } # handle pid my $rundir = '/var/run/sqdproc'; mkdir $rundir unless -d $rundir; if ($command eq 'stop') { $pid = Proc::PID::File->running(name => "sqd", dir => $rundir); print STDERR "Stopping process.. "; store $workers, $datafile; kill 2, $pid; print "ok!\n" and exit; } if ($command eq 'status') { $pid = Proc::PID::File->running(name => "sqd", dir => $rundir); if ($pid) { print STDERR "Process running, pid $pid\n" and exit; } else { print STDERR "Not running\n" and exit; } } $SIG{INT} = sub { $::exit = 1; close $::fifo }; print STDERR "Starting process.. \n"; Proc::Daemon::Init; my $pid = Proc::PID::File->running(name => "sqd", dir => $rundir); mkfifo($fifo_path, 0777) unless -e $fifo_path; # XXX mkfifo open (my $fifo, "<", $fifo_path) or die $!; while (1) { exit if $::exit; while (<$fifo>) { chomp $_; my ($c, $user, $dir) = split /\s+/, $_; $user ||= 0; my $tmp = "C $c USER $user DIR $dir\n"; `echo "$tmp" >> /tmp/sqd.log`; if ($c =~ m/create/i) { my $daemon = Proc::Daemon->new; my $username = `getent passwd $user | awk -F: '{print \$1}'`; chomp $username; my $com= "su - $username -c 'perl -s /home/jj/svn/main/misc/queueproc/sqd-daemon.pl $dir'"; `echo "$com" > /tmp/u`; my $dpid = $daemon->Init({ exec_command => "$com", }); $workers->{$dpid} = {pid=>$dpid, daemon=>$daemon, dir=>$dir, uid=>$user}; store $workers, $datafile; } } sleep 2; } close $fifo; sub write_to_fifo { my $str = shift; open(my $fifo, ">", $fifo_path) or die $!; print $fifo $str; close $fifo; }