Linux Equivalent to Windows Service Functions? - linux

I'm trying to find the Linux equivalent to Windows Service Functions. For example, Windows has ServiceMain for the entry point, SetServiceStatus to set a status, RegisterServiceCtrlHandler, and HandlerEx to respond to control codes such as start, pause and stop requests, etc.
I checked in W. Richard Steven's Advanced Programming in the UNIX® Environment, but I guess its a bit dated for the task. Searching for "linux service api" and "linux ipc service start stop" (and similar) are producing some http and database results, but nothing too useful.
Would anyone know the C interface for writing Linux service programs?

Linux services differ much:
You develop a script (rarely binary) to handle start/stop/status
command-line parameters (to start Your standalone Main() app/process or to do anything
else)
"registration" is done by putting that script into
/etc/rc.d/init.d/ and creating corresponding
/etc/rc.d/rc{level}.d/S{order} symbolic link(s)
there is no
out-of-the-box support/idea/paradigm of service-dependencies or
auto-restart
If You run:
/sbin/service --status-all
it'll run /etc/rc.d/init.d/ scripts with "status" parameter

Related

How to run application on linux in the background but leave possibility to interact with it?

Requirements:
I want to run my application on linux in the background (at startup of course).
I want to be able to call start/stop/restart commands directly from console (it have to be simple just like for /etc/init.d - just call simple command directly from console).
I want to be able to call status - and I want that this command will somehow get the actual status of application returned by itself. I thought that I can call some method which returns String or just use stdin to send command but when I do noup .. &, or start-stop-daemon, then the stdin is detached. Is there a simple way to attach stdin back to the application (I've seen that I can create a pipe, but this is pretty complitated). Or what is the best way to communicate with application after it is started as a daemon (I can make a socket and connect through telnet for example, but I am looking for simpler solution and possibility to do it directly from console, without starting telnet first)? Ideally it will be great to get the possibility to send any command, but simple status will be sufficient (but again - it have to communicate with the application to get that status somnehow)
I have found many different answers. Some of them says to simply use nohup and &, and some others says that nohup and & is old fashion. Some answers says to use start-stop-daemon or JSvc (for java). But it seems that none of them will suffice this 3 requirements from me.
So... What are the simplest possibilities for all of 3 requirements to be met?
PS. I don't want to use screen. The application must be run as a linux daemon.
PPS. Application is written in Java but I am looking for generic soluction which is not limited to java.
You should create a command line tool for communicate with a daemon in way you need. The tool itself can use TCP/IP or named pipes.
And then use cli-tool start|stop|restart|status from console.
If you need to start a daemon at startup sequence (before user login) you have to deal with init system (init.d, systemd, OpenRC, etc...).
Dragons be here:
Be sure that init doesn't restart your daemon after manual stop via cli.
Command line tool itself runs with unprivileged user rights, so restart may be hard if first startup script use superuser rights or application-specific user and, especially in case deep init integration, you might have to use sudo cli-tool start.
To avoid this one possible solution is to make wrapper daemon, that runs forever via init and control the underlying application (start-stop) with proper rights.
Cons: Develop two additional tools for a daemon.
Pros: Wrapper daemon can operate as a circuit breaker between superuser/specific user and userspace.

Programmatically start systemd service or test if service running

I need to start a service and (later) detect if it running from within a C++ program. Is there a simpler approach than invoking systemctl with suitable arguments and parsing the output?
The source of the service is entirely under my control. (Currently it is written in bash, but a C++ wrapper is entirely possible.)
(I've had a brief look at DBus - it is clearly very powerful, but fails the "simpler" test.)
The source of the service is entirely under my control. (Currently it is written in bash, but C++ is entirely possible.)
The code is for an embedded device running a variant of Debian Jessie. Portability is not a major concern (but obviously the answer will be more useful to others if it is portable).
Most programs are written with the other way in mind (even in pre-systemd days).
Typical services (those having and started with a single server process) are writing their PID (as an ASCII number on a single line) in some /var/run/foobar.pid file at their startup. If you adopt such a convention in your service, you can read that file using fscanf then check that the process is running with kill(pid, 0); (of course, you cannot be certain that it is the same service, but it probably would be).
I have right now more than 20 files matching /var/run/*.pid, notably /var/run/sshd.pid & /var/run/atd.pid
So, assuming you can improve the code of your service FooBar (if that functionality is not there), change its code to write its pid into /var/run/foobar.pid; this is a documented convention.
If you can change the service, you might have it providing some ping or nop functionality; so you would add to it some RPC facility which justs check that the service is running (and could also give some additional information, like the version of the program, etc.). Most existing Linux services have such feature.
Why not flip the problem around? No parsing would be needed.
ttm.update.service will do the following.
systemctl stop ttm.service
systemctl disable ttm.service
#do you update here
#if the service configs changed do
systemctl daemon-reload
systemctl enable ttm.service
systemctl start ttm.service
ttm.service would never have to worry about the updater, it just runs and do it's job.

Automating services with Linux OS starting up and shutting down

I have a script to start and stop my services. My server is based on Linux. How do I automate the process such that when OS is shutdown the stop script runs and when it is starting up, the start script runs?
You should install init script for your program. The standard way is to follow Linux Standards Base section 20 subsections 2-8
The idea is to create a script that will start your application when called with argument start, stop it when called with argument stop, restart it when called with argument restart and make it reload configuration when called with argument reload. This script should be installed in /etc/init.d and linked in various /etc/rd.* directories. The standard describes a comment to put at the beginning of the script and a uitlity to handle the installation.
Please, refer to the documentation; it is to complicated to explain everything in sufficient detail here.
Now that way should be supported by all Linux distribution. But Linux community is currently searching for better init system and there are two new, improved, systems being used:
systemd is what most of the world seems to be going to
upstart is a solution Ubuntu created and sticks to so far
They provide some better options like ability to restart your application when it fails, but your script will then be specific to the chosen system.

What are the advantages and disadvantages of using the upstart script or forever script in a context of running node.js scripts ??

I am a node.js developer. I use Amazon ec2 to deploy my node.js apps.
I want to have my node.js service running permanently - restarted if it fails for any reason.
I came across 2 tools . Forever and Upstart
Is there any advantages of using one over the other ?
Is there any other tool which is better ?
Upstart is a system service controller, similar to SysV Init and will start/stop/restart essentially any service registered for it, Node.js-based or not, and it will also automatically start services on system start for you. But Upstart is essentially specific to Ubuntu, and Upstart-specific services won't run on other Linux distros.
Upstart has a SysV Init compatibility layer that you could target,instead, to maintain as broad of a compatibility layer as possible.
Forever is a Node.js application that monitors and restarts other Node.js applications as needed, and as defined by its configuration JSON. Lots of options and fine-grained control over your service without the effort that would be needed to duplicate it in a custom SysV Init script. However, Forever isn't a system service, so if the server is restarted, you'll have to manually start your forever scripts again.
Beyond that, if all you need is something that will restart your script if/when it crashes, and you don't care about it starting automatically on system start, all you need is a bash script as simple as:
#!/bin/bash
while true
do
node ./myScript.js
done
Just to correct a misleading statement in the accepted answer...it is not true that upstart is an Ubuntu-only technology. See:
https://serverfault.com/questions/291546/centos-6-and-upstart
http://searchenterpriselinux.techtarget.com/tip/RHEL-6-ditches-System-V-init-for-Upstart-What-Linux-admins-need-to-know
http://en.wikipedia.org/wiki/Upstart#Adoption
With that, I think it is a much more compelling solution.

Automated deployment of files to multiple Macs

We have a set of Mac machines (mostly PPC) that are used for running Java applications for experiments. The applications consist of folders with a bunch of jar files, some documentation, and some shell scripts.
I'd like to be able to push out new version of our experiments to a directory on one Linux server, and then instruct the Macs to update their versions, or retrieve an entire new experiment if they don't yet have it.
../deployment/
../deployment/experiment1/
../deployment/experiment2/
and so on
I'd like to come up with a way to automate the update process. The Macs are not always on, and they have their IP addresses assigned by DHCP, so the server (which has a domain name) can't contact them directly. I imagine that I would need some sort of daemon running full-time on the Macs, pinging the server every minute or so, to find out whether some "experiments have been updated" announcement has been set.
Can anyone think of an efficient way to manage this? Solutions can involve either existing Mac applications, or shell scripts that I can write.
You might have some success with a simple Subversion setup; if you have the dev tools on your farm of Macs, then they'll already have Subversion installed.
Your script is as simple as running svn up on the deployment directory as often as you want and checking your changes in to the Subversion server from your machine. You can do this without any special setup on the server.
If you don't care about history and a version control system seems too "heavy", the traditional Unix tool for this is called rsync, and there's lots of information on its website.
Perhaps you're looking for a solution that doesn't involve any polling; in that case, maybe you could have a process that runs on each Mac and registers a local network Bonjour service; DNS-SD libraries are probably available for your language of choice, and it's a pretty simple matter to get a list of active machines in this case. I wrote this script in Ruby to find local machines running SSH:
#!/usr/bin/env ruby
require 'rubygems'
require 'dnssd'
handle = DNSSD.browse('_ssh._tcp') do |reply|
puts "#{reply.name}.#{reply.domain}"
end
sleep 1
handle.stop
You can use AppleScript remotely if you turn on Remote Events on the client machines. As an example, you can control programs like iTunes remotely.
I'd suggest that you put an update script on your remote machines (AppleScript or otherwise) and then use remote AppleScript to trigger running your update script as needed.
If you update often then Jim Puls idea is a great one. If you'd rather have direct control over when the machines start looking for an update then remote AppleScript is the simplest solution I can think of.

Resources