system daemon pear - php

Question,
How can I spurn another process within a daemon?
I want to use the pear system daemon library to spurn a daemon and then spurn off processes within that daemon.
So daemon runs
and then a new process is spurn off and does calculation separately
then other processes are spurn off that runs separate from the daemon.
meanwhile, daemon keeps executing code and spurns off more processes
how can I accomplish this?

System_Daemon only handles startup/shutdown handling, general signal handling and logging.
If you want to spawn new processes from your PHP code, you need to use PHP's pcntl functions.

Spurn? I assume you mean spawn.
PHP has lots of functions for creating processes - however (AFAIK) they are all blocking (except for pcntl_exec which replaces the current process)
A quick sift through the documentation for the Pear System Daemon, this only handles the process of daemonizing the process - not of running a server process and handling multiple clients. How you go about implementing this will have a big impact on how you handle starting up new processes.
One solution would be to fork an instance of the current process to handle an incoming connection - there's an example on the socket_accept() doc page. Then it doesn't matter if the process you start is via a blocking call or not.
But a much simlper solution would be not to bother with a daemon / forking / sockets and just invoke it via [x]inetd using stdio
C.

I had the same problem before. The solution I did was to have one system_daemon calling another system_daemon through exec. You need to change the appPidLocation option to run a new instance of the same code.
To see the list of options I looked at the code of system_daemon.

Related

Pass SNMP trap packet to a php daemon on Ubuntu

I have a Ubuntu server which is collecting incoming SNMP traps. Currently these traps are handled and logged using a PHP script.
file /etc/snmp/snmptrapd.conf
traphandle default /home/svr/00-VHOSTS/nagios/scripts/snmpTrap.php
This script is quite long and it contains many database operations. Usually the server receives thousands of traps per day and therefore this script is taking too much CPU time. My understand is this is due to high start-up cost of the php script every-time when a trap received.
I got a request to re-write this and I was thinking of running this script as a daemon. I can create an Ubuntu daemon. My question is how can I pass trap-handler to this daemon using snmptrapd.conf file?
Thank you in advance.
One suggestion is to use mysql support thats built into 5.5 of snmptrapd. That way you can use mysql as a queue and process the traps in bulk.
details of this are on the snmptrapd page: http://www.net-snmp.org/wiki/index.php/Snmptrapd
If not using mysql another option is to use a named pipe.
Do mkfifo snmptrapd.log
Now change snmptrapd to write to this log. Its not a file but it looks like one. You then write another daemon to watch the named pipe for new data.
You can probably use php-fpm / php-fcgi to minimize PHP script start-up cost.
Although, you probably need to write some wrapper shell script to forward request from snmptrapd to fcgi protocol.
But at first I'd recommend checking the PHP script. PHP start-up cost is not that high that few requests per minute should rise CPU usage notably.

Running a PHP process as a daemon while safely killing it from background

We are running a PHP Daemon which look into a queue, receives worker jobs and spawns the worker to handle it. The workers themselves acquire a lock on a specific location before proceeding.
We spawn the Daemon as nohup background processes.
This entire architecture seems to work, except when we have to kill the processes, for whatever reason. If we kill them using -9, there is no way to trap it in the worker process and release the locks before dying.
If we use anything less than -9 (like TERM or HUP), it doesn't seem to be received by either the daemon or the worker processes.
Has anybody solved this problem in a better way?
(ps: BTW, Due to other considerations, we may not be able to change our language of implementation, so please only consider PHP based solutions)
I had related problems once too. Let me explain. I had a php 'daemon' that worked like a downloader. It accessed feeds periodically and downloads (laaaarge) content from the net. The daemon had to be stopped at a certain time, lets say 0500 in the morning to prevent it from using the whole bandwith during daytime. I decided to use a cronjob to send SIGTERM to the daemon at 0500.
In the daemon I had the following code:
pcntl_signal(SIGTERM, array($this, 'signal_handler'));
where signal_handler looked like this:
public function signal_handler($signal) {
// some cleanup code
exit(1);
}
Unfortunately this did not work :|
It took me a time to find out what's going on. The first thing I figured out was that I'll have to call the method pcntl_signal_dispatch() on init to enable signal dispatching at all. Quote from the doc (comments):
If you are running PHP as CLI and as a "daemon" (i.e. in a loop), this function must be called in each loop to check if new signals are waiting dispatching.
Ok, so far, it seemed working. But I realized quickly that under certain conditions even this will not work as expected. Sometimes the daemon could only being stopped by kill -9 - as before. :|
So what's the problem?.. Answer: My program called wget to download the files via shell_exec. The problem is, that shell_exec() blocking waits until the child process has terminated. During this blocking wait no signal processing is done, the process can only being terminated using SIGKILL - what is hard. Also a problem was that child processes had to be terminated one by one as they became zombie processes after killing the father.
My solution to this was to execute the child process using proc_open() and the use stream_select() on it's output for non blocking IO.
Now it works like a charm. :) If you need further information don't hesitate to drop a comment.
Note If you are working with PHP < 5.3 then you'll have to use `
declare(ticks=1);
instead of pcntl_signal_dispatch(). You can rfer to the the documentation of pcntl_signal() for that. But if possible you should upgrade to PHP >= 5.3
The problem was solved just by adding ticks:
// tick use required as of PHP 4.3.0
declare(ticks = 1);
Leaving this alone was causing my code not to work.
*(It's unfortunate that the documentation of pcntl_signal doesn't mention it in a lot more attention grabbing way.)*
You need to catch the signal (SIGTERM). This can be achieved via the function pcntl_signal. This will give you the option to perform any necessary functions before calling exit.

Running an infinite loop in cron job

Running an infinite loop in cron job.Suppose, i have written a php based script to run on my server computer using cron job, and i want to use infinite loop in that php script.Any ideas for running an infinite loop in cron job.
Infinite looping applications are usually called daemons. They are system services that offer some kind of constant processing and/or the readiness to accept some potential incoming processing activities.
Gearman is a system daemon you can install than can handle various tasks you give it. It's a complex tools that allows many things but it could be used to implement your necessities.
PHP::Gearman is a Gearman client that talks to the Gearman daemon and sends tasks to the daemon specifying the conditions under which the task must be executed.
The limitations that #Jeffrey emphasized about PHP are true because PHP was designed as a share nothing architecture (one page load equals one script execution - each page load works under its own data context).
Perhaps System Daemon (a pear package) may assist in overcoming some or all of the limitations mentioned above. I haven't used it so I can't tell you much more about it but it's as good a place to start as any.

How to communicate with a python daemon from PHP scripts

I'm making a scan server for my company, which will be used to launch scans from tools such as nessus, nmap, nikto etc. I've written the pages in PHP, but I need to have control over the subsequent processes (spawned with nohup and backgrounded with &) as I need to perform various actions once the scans have completed (such as emailing them, downloading reports off the nessus server etc).
I was advised on here to create a python daemon that the PHP pages communicated with. I've googled endlessly, but I can't find anything that explains the logic behind the communication from a beginner's perspective (coding a daemon will be my most advanced project yet). I'm aware of IPC and unix domain sockets for example, but not sure as to how I can employ them in my situation. As such, I'm after some advice or pointers as to what I should do.
I was thinking I could create a python script with a while loop that constantly checks to see if the process has terminated and when it does, perform the appropriate post process termination action. The script would be daemonized so it runs in the background and I would call it from the PHP pages with the PID as a parameter, which I could access with the argparse module for example.
Am I on the right lines in terms of logic - or are there better solutions?
Any help, or just something to google, is much appreciated! Thanks
I think something like gearman would certainly make it easier to implement this.
Gearman is a job server which lets you start jobs, query if the job is still running and fetch the output of the job (as text).
It supports PHP and Python (among others).
(This answer made me feel like a salesman).
So your plan is: PHP spawns nmap & a watchdog. Watchdog keeps polling for nmap to finish running and then does some post processing once its done.
Slightly cleaner would be:
PHP spawns a 'process manager' (which also you write). This process manager is basically a program that executes nmap in a child process, waits for this child process to finish (using the 'wait' system call, which for example in C looks like: http://linux.die.net/man/2/wait), and does the post processing.
It will also be more efficient because a 'wait' will probably be cheaper than repeatedly checking if the PID has terminated.
If you like python more than C, python has subprocess management too:
http://docs.python.org/library/subprocess.html

How best to control (issue command signals to) a PHP-based Daemon script?

I've created a PHP Daemon script to continually monitor a particular directory on the server's file system for new files, and then process and archive them.
Note: I'm using a php Daemon class provided at: http://www.phpclasses.org/browse/file/8958.html
I've got the script running, but I need a way to interface with the daemon and issue commands. One really useful command, for instance, would be "STOP"! :) I currently have to kill the process manually.
I've done this before using control files (i.e., check the file for a new command, execute it if one exists, then clear the file). I've also used sockets, but this problem doesn't really call for any networking. Is there a better, more elegant or natural way to send command signals to the Daemon?
I did find this:
PHP Daemon/worker environment
But I'm afraid I don't fully grasp how to use the provided code.
A possible solution would be to use signals -- see pcntl_signal, for instance : your PHP daemon would listen for signals, and you'd only have to send signals from "outside".
That's a way that is quite often used on UNIX/Linux -- but note that pcntl_* functions will not be available on windows. (The class you posted is already using pcntl* functions, so nothing new here)
On *nix you can use signals to control your daemon; seepcntl_signal() and the signal(7) man page.

Categories