Killing Processes

O

Oldbitcollector

Ok, I've done a couple days worth of searching on this one, and am
stuck. Here's the situation. I have a Linux/PERL script that runs from
inetd when someone telnets to the proper port. I have multiple copies
of this script running at any given time (multi user). When someone
simply drops their end of the connection, the program just stays
running hogging 99% (if it can take it) of the CPU.

I've tried to use alarm(300); while this works, it kills other valid
copies of the program when it drops the one I intended. Because they
all have the same name.

I've considered parsing a copy of "ps -x" to obtain which copies of the
script have been running for more than 5min, but this seems the sloppy
way to go. The nice part of this solution is that a running script
stays around 0:03 while it's under operation, then then starts adding
time after the user drops connection. They are obvious to spot.

Can anyone here provide some direction?

Thanks
Jeff
 
P

Peter J. Holzer

Oldbitcollector said:
Ok, I've done a couple days worth of searching on this one, and am
stuck. Here's the situation. I have a Linux/PERL script that runs from
inetd when someone telnets to the proper port. I have multiple copies
of this script running at any given time (multi user). When someone
simply drops their end of the connection, the program just stays
running hogging 99% (if it can take it) of the CPU.

You probably forgot to check for EOF on stdin.
I've tried to use alarm(300); while this works, it kills other valid
copies of the program when it drops the one I intended. Because they
all have the same name.

Extremely unlikely. alarm kills only the process which called it, not all
processes with the same name. More likely each of your processes is killed
after 5 minutes by itself.

hp
 
X

xhoster

Oldbitcollector said:
Ok, I've done a couple days worth of searching on this one, and am
stuck. Here's the situation. I have a Linux/PERL script that runs from
inetd when someone telnets to the proper port. I have multiple copies
of this script running at any given time (multi user). When someone
simply drops their end of the connection, the program just stays
running hogging 99% (if it can take it) of the CPU.

So why not fix the problem so it doesn't do that anymore? An ounce of
prevention is worth a pound of cure.
I've tried to use alarm(300); while this works, it kills other valid
copies of the program when it drops the one I intended. Because they
all have the same name.

Eh, I don't think so. That isn't the way alarm works, at least not on
my system.

samename.pl:
fork and do {
alarm 5;
sleep;
};
sleep 10;
warn "still alive"
__END__

When I run samename.pl, after 5 seconds the parent exits on the alarm.
After five more the child claims to still be alive. (But you know how
children lie...)

Xho
 
R

robic0

Ok, I've done a couple days worth of searching on this one, and am
stuck. Here's the situation. I have a Linux/PERL script that runs from
inetd when someone telnets to the proper port. I have multiple copies
of this script running at any given time (multi user). When someone
simply drops their end of the connection, the program just stays
running hogging 99% (if it can take it) of the CPU.

I've tried to use alarm(300); while this works, it kills other valid
copies of the program when it drops the one I intended. Because they
all have the same name.

I've considered parsing a copy of "ps -x" to obtain which copies of the
script have been running for more than 5min, but this seems the sloppy
way to go. The nice part of this solution is that a running script
stays around 0:03 while it's under operation, then then starts adding
time after the user drops connection. They are obvious to spot.

Can anyone here provide some direction?

Thanks
Jeff

Hey Jeffry,
Are u using Net::Telnet ?

"I have a Linux/PERL script that runs from
inetd when someone telnets to the proper port."

Inetd, is that a firewall debug program?
Dunno, not an expert, just asking?

Thanks
-robic0-
 
O

Oldbitcollector

You probably forgot to check for EOF on stdin.

Could you expand on this a little bit? Yes, the software always stops
at
a keyboard entry routine, waiting for user input. This would be the
right
place to do something.

My main part of my input routine looks like this...

sub keyin {
$keyin="";
$idletime="";
$done='0';
while ($done eq '0') {
$key=getc(STDIN);
$idletime++;
#if ($idletime eq '100') {$show="$idletime";
&show;}

if (ord($key) eq 0x0D ) {
print $key;
$done='1';
}
elsif(ord($key) eq 0x0a ) {
print $key;
$done='1';
}
elsif(ord($key) eq 0x14 ) {
if(length($keyin) gt 0) {
#delete key
print $key;
$keyin=substr($keyin,0,length($keyin)-1);
}
}
else {
if ($texthide eq 'yes') {print "*";}
if ($texthide eq 'no') {print $key;}
#print ord($key);
$keyin.=$key;
}

}

}


Jeff
 
O

Oldbitcollector

Hey Jeffry,
Are u using Net::Telnet ?

No this is a system of my own making. Prob the strangest use for perl
this group has seen in a while. It's an old fashion C/G BBS system
written in perl.

Jeff
 
O

Oldbitcollector

I don't believe it... The answer was right in front of me the whole
time..

The addition of the following takes care of the problem.

if ($key eq "") { &terminateprogram }

Thanks allow me to think "out loud"

Jeff
 
J

Josef Möllers

robic0 said:
On 11 Mar 2006 09:08:56 -0800, "Oldbitcollector" <[email protected]>
wrote: [...}

Hey Jeffry,
Are u using Net::Telnet ?

"I have a Linux/PERL script that runs from
inetd when someone telnets to the proper port."

Inetd, is that a firewall debug program?
Dunno, not an expert, just asking?

inetd (or xinetd) is the "inetrnet superdaemon" on Unix and Linux systems.
Rather than have a plethora of small server processes each starting up,
setting up their network ports and then eating up memory resources waiting
for connection requests that might never come, a single server process
([x]inetd) is configured to set up the internet ports for a set of services
and then this single process waits for a connect request on any of these
ports. If a connection request comes in, it spawns off and execs the real
server process, handing the connection on stdin/stdout/stderr (not 100%
sure about stderr) to the real server process.

This has several advantages:
1. only a single process is waiting (maybe for a connection request that
never comes) and consuming memory resources,
2. only a single process needs to perform host validation and access
restriction checking (hosts.allow/hosts.deny)
3. the actual server process gets the connection on stdin/stdout, allowing
simpler code in the server process (e.g. I've set up a logging server for a
project that took a hefty server process on Windows using only a very few
number of lines of Perl code on Linux and xinetd).

HTH,

Josef
 
O

Oldbitcollector

Ok, I thought I had it beat, but forgot that I'm also using
Term::Readkey in another section of the script. The original
getc<STDIN> doesn't work here, because I don't need it to wait for a
keypress this time, so Readkey was used instead. The same problem has
popped up, because this routine runs as a loop until the user types
/quit to exit.

Here's some of what it looks like....

loop:
$ckey="";
$ckey=Readkey(1);

## Various checking for delete key, etc here...

$ckey.=$ckey;
if ($ckeyin eq 'quit' ) {&terminate}

## Send information to the chatfile, etc.

goto loop;


The same problem crops up again, when someone drops their connection,
the loop continues to run. I can't use an if ($ckey eq "") because
that happens frequently in this use. What can I look for to find an
EOF?

Thanks,
Jeff
 
X

xhoster

Oldbitcollector said:
Ok, I thought I had it beat, but forgot that I'm also using
Term::Readkey in another section of the script. The original
getc<STDIN> doesn't work here, because I don't need it to wait for a
keypress this time, so Readkey was used instead. The same problem has
popped up, because this routine runs as a loop until the user types
/quit to exit.

Here's some of what it looks like....

loop:
$ckey="";
$ckey=Readkey(1);

my copy of Term::ReadKey doesn't have a "Readkey" sub, but it does have
a "ReadKey".

## Various checking for delete key, etc here...

$ckey.=$ckey;
if ($ckeyin eq 'quit' ) {&terminate}

## Send information to the chatfile, etc.

goto loop;

The same problem crops up again, when someone drops their connection,
the loop continues to run. I can't use an if ($ckey eq "") because
that happens frequently in this use. What can I look for to find an
EOF?

As far as I can tell, Term::ReadKey doesn't provide an easy way to
distinguish between the undef returned due to time-outs and the undef
returned due to EOF. And the eof function itself won't easily help you, as
it blocks indefinitely which apparently you don't want to happen. So my
first recommendation would be to forgo Term::ReadKey in favor of some
select (or IO::Select) based method.

Howver, if you want to keep using Term::ReadKey, you could take advantage
of the fact that (at least on my system) ReadKey returns immediately upon
eof but waits for the time-out period if not eof. So if it return many
times within one second (assuming you are using 1 second timeout) then you
are at eof.

use Term::ReadKey;
my $time=0;
my $count=0;
while (1) {
my $c=ReadKey(1);
if ($time==time()) {
last if ++$count==10;
} else {
$time=time; $count=0};
print defined $c?1:0, "\t$c\t$@\t$!"
}

There might also be a way to detect eof with GetControlChars, but I
couldn't figure it out.

Cheers,

Xho
 
C

Charles DeRykus

Peter said:
You probably forgot to check for EOF on stdin.


Extremely unlikely. alarm kills only the process which called it, not all
processes with the same name. More likely each of your processes is killed
after 5 minutes by itself.

The only wild possibility that occurred to me was that perhaps
there was a signal handler killing process groups in the event
of a timeout, eg.,

local $SIG{ALRM} = sub { kill 'TERM', -$$; };
 
O

Oldbitcollector

Again, Thank you guys for all of your help! I implemented the timer on
Readkey and it's working perfectly. No more abandoned processes, and
the CPU couldn't be happier. :)
If you guys would like to see what the fuss is for, and see the most
odd application in PERL, you are welcome to take a peek. As said
before, this is an Old fashion, 80's style BBS. You'll need a C/G
terminal to connect. (http://www.paradroid.net/cgterm/) and in option
D, type: bbs.petscii.com 6400 -- Might bring back some memories for
some oldtimers.

Quick question, Is it possible to stat a file for a more exact time
that just mins. and hours?
I'd to see exactly what min/second that a file was last modified or
accessed?

Thanks again, I bow to the perl gods of this group.

Jeff
 
J

J. Gleixner

Oldbitcollector said:
Quick question, Is it possible to stat a file for a more exact time
that just mins. and hours?
I'd to see exactly what min/second that a file was last modified or
accessed?

perldoc -f stat

"
9 mtime last modify time in seconds since the epoch
...."
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,021
Latest member
AkilahJaim

Latest Threads

Top