Storing pid file for a daemon run as user
If it's being run for a user, let's see, what sort of storage exists that is user-specific.
Hmmm.
That's it! The home directory. I knew it would come to me eventually :-)
Sorry for the light jab. Seriously, I would just stash the PID into $HOME/.daemon.pid
or ~/.daemon.pid
(how you name the file is up to you of course).
This is, of course, assuming you will only have one daemon running for a user. If not, you'll need to be a bit trickier.
And hopefully allaying your fears that a user will inadvertently delete unknown files in their home directory, that's why you make it "hidden" by starting it with a .
character.
Most non-experienced users should never even see these and experienced users should know better than to muck about with them.
Preferred location for PID file of system daemon run as non-root user
Nice question :), I'm having exactly the same at moment. I'm not sure if this is the correct answer but I hope it helps and I would appreciate feedback as well.
I've googled around and found that registering the per user daemon as a dbus service is an elegant solution. dbus could make sure that the service runs just once. no need for a pidfile.
Another solution (my current) would be to create the PID file in a directory like:
$HOME/.yourdaemon/pid
After your comment I realized, that you cannot write to home. I would suggest to look into dbus
Update
I have an idea. What if you are using /tmp, but looking for a pidfile which is called yourdaemon.pid.UNIQUE_KEY and is owned by the daemon's user? This should work fine.
UNIQUE_KEY
should be random generated (preferred is using tempnam as it is race condition proof).
Must my pidfile be located in /var/run?
I wouldn't put a pidfile under an application installation directory such as /opt/my_app/whatever
. This directory could be mounted read-only, could be shared between machines, could be watched by a daemon that treats any change there as a possible break-in attempt…
The normal location for pidfiles is /var/run
. Most unices will clean this directory on boot; under Ubuntu this is achieved by /var/run
an in-memory filesystem (tmpfs).
If you start your daemon from a script that's running as root, have it create a subdirectory /var/run/gmooredaemon
and chown it to the daemon-running user before su
ing to the user and starting the daemon.
On many modern Linux systems, if you start the daemon from a script or launcher that isn't running as root, you can put the pidfile in /run/user/$UID
, which is a per-user equivalent of the traditional /var/run
. Note that the root part of the launcher, or a boot script running as root, needs to create the directory (for a human user, the directory is created when the user logs in).
Otherwise, pick a location under /tmp
or /var/tmp
, but this introduces additional complexity because the pidfile's name can't be uniquely determined if it's in a world-writable directory.
In any case, make it easy (command-line option, plus perhaps a compile-time option) for the distributor or administrator to change the pidfile location.
Best practice: PID file for unix daemon
The actual daemon process (the child).
According to the daemon
man page provided by the systemd
package and viewable on a RHEL 7 (or CentOS 7) host by running man daemon
:
- In the daemon process, write the daemon PID (as returned by getpid())
to a PID file, for example /run/foobar.pid (for a hypothetical daemon
"foobar") to ensure that the daemon cannot be started more than once.
This must be implemented in race-free fashion so that the PID file is
only updated when it is verified at the same time that the PID
previously stored in the PID file no longer exists or belongs to a
foreign process.
You can also read the man page on the internet.
Reference for proper handling of PID file on Unix
As far as I know, PID files are a convention rather than something that you can find a respected, mostly authoritative source for. The closest I could find is this section of the Filesystem Hierarchy Standard.
This Perl library might be helpful, since it looks like the author has at least given thought to some issues than can arise.
I believe that files under /var/run are often handled by the distro maintainers rather than daemons' authors, since it's the distro maintainers' responsibility to make sure that all of the init scripts play nice together. I checked Debian's and Fedora's developer documentation and couldn't find any detailed guidelines, but you might be able to get more info on their developers' mailing lists.
How to capture pid of a linux daemon run from init.d
Try using start-stop-daemon(8)
with the --pidfile
argument in your init script. Have your program write its PID to a specified location (usually determined in a configuration file).
What you have to look out for is stale PID files, for instance, if a lock file persisted across a reboot. That logic is best implemented in the init script itself, hence the --exec
option to start-stop-daemon
.
E.g, if /var/run/foo.pid
is 1234
, and /proc/1234/exe
isn't your service, the lock file is stale and should be quietly removed, allowing the service to start normally.
As far as your application goes, just make sure the location of the lockfile is configurable, and some means exists to tell the init script where to put it.
For instance: (sample: /etc/default/foo) :
PIDFILE=/var/run/foo.pid
OTHEROPTION=foo
Then in /etc/init.d/foo :
[ -f /etc/default/foo ] && . /etc/default/foo
Again, other than writing to the file consistently, all of this logic should be handled outside of your application.
What is a .pid file and what does it contain?
The pid files contains the process id (a number) of a given program. For example, Apache HTTPD may write its main process number to a pid file - which is a regular text file, nothing more than that - and later use the information there contained to stop itself. You can also use that information to kill the process yourself, using cat filename.pid | xargs kill
Related Topics
How to Reserve Virtual Memory in Linux
Parsing Data from Ifconfig with Awk or Sed
Haskell Ghc Compiling/Linking Error, Not Creating Executable. (Linux)
Nacl Helper Process Running Without a Sandbox Error Using Chrome Through Selenium in Linux
How to Set Dt_Rpath or Dt_Runpath
Sed Is Printing a Substituted Line Twice
How to Determine the Precise Set of Environment Variables a Systemd Environmentfile Would Set
Yocto Build for a Static Library Fails with Error "No Match Found"
Dynamic Loading of Shared Objects Using Dlopen()
Access Bash Positional Parameter Through Variable
Explanation of Memcpy Memmove Glibc_2.14/2.2.5
Objdump and Resolving Linkage of Local Function Calls
Difference Between Trap Flag (Tf) and Monitor Trap Flag