-
-
Notifications
You must be signed in to change notification settings - Fork 359
Technicalities: Work with PID and state file paths
Aggregating codebase research done in various issues, and linking to some related others, to keep notes organized:
- https://github.com/networkupstools/nut/issues/123
- https://github.com/networkupstools/nut/issues/1299
- https://github.com/networkupstools/nut/issues/1712
- https://github.com/networkupstools/nut/issues/1717
- https://github.com/networkupstools/nut/pull/1719
- https://github.com/networkupstools/nut/issues/1727
- https://github.com/networkupstools/nut/issues/1728
After a bit more digging in current codebase, I can say that NUT unprivileged daemons (drivers and upsd) default to using the ALTPIDPATH
in fact -- which in turn defaults to STATEPATH
e.g. /var/state/ups
since both daemon types exchange pipe files there so may write there, but some package recipes configure
it to e.g. /var/run/nut
.
This can be seen by code lines preparing a pidfn
(usually) with altpidpath()
(see common/common.c
) in drivers/main.c
, drivers/upsdrvctl.c
and server/upsd.c
.
And then it gets messy in same common/common.c
with:
-
writepid()
which optionally usesPIDPATH
(as defined, no./nut
subdir) if filename
is not absolute, and with -
sendsignal()
which combinesPIDPATH
(as defined, no./nut
subdir) and theprogname
to wrapsendsignalfn()
(which reads PID from that absolute filename and signals the process in OS-dependent manner).
These latter usages imply that PIDPATH
is expected to be writable by nut
processes and should not be the root-secured system location (e.g. /var/run
directly) unless NUT tools and daemons run as root
; can be /tmp
however.
I'll post a clean-up PR to clarify this in configure
script comments and docs, and "reference" init-scripts and packaging templates which use $PIDPATH/nut
to confuse matters more.
Also linking to #123 which creeps out to other big discussions on PID files :)
Checking references to the methods mentioned above wit a focus on PIDPATH
usage in current state of master
branch:
:; git grep -E '(writepid|sendsignal|altpidpath) *\('
-
clients/upslog.c
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/clients/upslog.c#L615-L617 --
writepid(pidfilebase);
just beforebecome_user()
so expected to beroot
at that point and may use even a privilegedPIDPATH
location. Thepidfilebase
isprog
name or set by argument.
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/clients/upslog.c#L615-L617 --
-
clients/upsmon.c -- the one explicitly documented consumer of
configure --with-pidpath
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/clients/upsmon.c#L2369-L2392 -- signals an older (running) instance of itself, using
sendsignal(prog)
(underPIDPATH
) in some cases -
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/clients/upsmon.c#L2470-L2488 --
writepid(prog)
just beforebecome_user()
(if running as parent-child pipe and changing privileges at all; saving child PID then), so expected to beroot
at that point and may use even a privilegedPIDPATH
location. - Note that if upsmon gets split into two processes, the parent part at https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/clients/upsmon.c#L2034 runs (for non-Windows case) until either the child process exits, or until it sends the message to call
shutdowncmd
(asroot
which is the purpose of this split). There is no separate PID file for the parent process.
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/clients/upsmon.c#L2369-L2392 -- signals an older (running) instance of itself, using
-
drivers/main.c
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/main.c#L903 prepares
buffer
with absolute driver PID file name underaltpidpath()
, used in https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/main.c#L918 and https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/main.c#L931-L933 to kill off an earlier instance if present, with full-pathsendsignalfn()
. -
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/main.c#L949-L953 calls
pidfn=buffer; writepid(pidfn);
to save the PID value before possibly forking and backgrounding the driver (if backgrounding is enabled). -
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/main.c#L1145-L1148 calls
writepid(pidfn);
to save the PID value after possibly forking and backgrounding the driver (if backgrounding is enabled). - Note the PID file is neither saved nor queried in foreground mode (e.g. competing driver instances are not killed off either).
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/main.c#L1145-L1148 calls
sendsignal()
only for WIN32 usecases (so not relying onPIDPATH
for POSIX builds)
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/main.c#L903 prepares
-
drivers/upsdrvctl.c
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/upsdrvctl.c#L159-L174 tries absolute
pidfn
variants underaltpidpath()
tostop_driver()
and exits if none of those is present -
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/upsdrvctl.c#L185-L224 further in
stop_driver()
uses the absolutely-pathedsendsignalfn()
in POSIX use-cases
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/drivers/upsdrvctl.c#L159-L174 tries absolute
-
scripts/Windows/wininit.c
- two WIN32 usecases of
sendsignal()
(so not relying onPIDPATH
for POSIX builds)
- two WIN32 usecases of
-
server/upsd.c :
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/server/upsd.c#L1600 prepares
pidfn
underaltpidpath()
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/server/upsd.c#L1686-L1697 makes use of
sendsignal*()
variants, withsendsignal()
specifically called only for WIN32 usecases (so not relying onPIDPATH
for POSIX builds) -
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/server/upsd.c#L1842-L1853 uses
writepid(pidfn)
with absolute path (so not relying onPIDPATH
)
-
https://github.com/networkupstools/nut/blob/ddbab26b5c595743bf02f9bb71b8d6ba18ce6bb2/server/upsd.c#L1600 prepares
Welcome to the Network UPS Tools (NUT) project Wiki, and feel free to contribute tricks and insights.
While there are several good entries in the menu, ones referenced most frequently in issue discussions include:
- Building NUT for in-place upgrades or non-disruptive tests and Using NIT (NUT Integration Test suite) sandbox
- Technicalities: Customizing (NUT) config files and scripts delivered by packaging
- Links to distribution packaging recipes and repository sections
- Troubleshooting
upsdrvctl
drivers not starting ("insufficient permissions on everything" or "Can't claim USB device [VVVV:PPPP]@0/0: Entity not found") possibly due to nut-driver-enumerator (NDE) services having been there before you with NUT 2.8.x, and "insufficient permissions" when starting USB drivers for a different PoV on this; see also an example unit deployment detailed in NUT systemd service units page - Changing NUT daemon debug verbosity
- Building NUT integration for Home Assistant
- Running NUT in an LXC container
- Troubleshooting eventual disconnections (Data stale) and CyberPower Systems (CPS) know-how
- NUT for Windows
- NUT HCL and DDL
- Code contributions, PRs, PGP and DCO
- NUT CI farm
Also keep in mind the documentation links from NUT website and the FAQ in particular.