You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
upsmon fails to start if the old pid happens to exist for an unrelated process #2463
If a previous upsmon.pid file is present at startup and an unrelated process by chance happens to exist with that pid, upsmon will fail to start with the following message:
Fatal error: A previous upsmon instance is already running!
Either stop the previous instance first, or use the 'reload' command.
Workaround:
My cron job that that checks running services using pidof will now delete upsmon.pid before attempting to restart upsmon.
Expected behavior:
If the name of the current process with the pid contained in upsmon.pid is unrelated to upsmon, then upsmon should start up normally instead of exiting with a failure.
Thanks, that's an interesting case, although the hard part can be looking up the process name for a PID across many platforms that all do it differently.
Just in case: is the problem happening at router start-up? Does your build of NUT there store the PID files in a persistent storage location, or in a tmpfs that should be empty after a reboot?
Also, which version of NUT is involved? I think with recent ones, a graceful exit of the daemon should have it delete the PID file.
The pid file is in /opt/var/run which is persistent. The /opt/etc/init.d/S15upsmon startup script isn't specifying a variable with the directory for the pid file so not sure how to override this to a non-persistent directory.
This problem only happened once after a non-graceful reboot of the router. I kept getting emails about upsmon not running so all subsequent attempts to start upsmon were also failing.
Since the entware startup scripts already perform a check of an already running process (below), perhaps a upsmon command-line argument to skip the redundant test at upsmon startup could be a workaround.
if [ -n "`pidof $PROC`" ]; then
echo -e " $ansi_yellow already running. $ansi_std"
return 0
fi
This is admittedly a fringe case that requires bad luck to occur.
For temporary files (PID, Unix socket, etc.), NUT uses generally several locations which are built into the binaries by configre script settings, but can be customized by environment variables such as NUT_STATEPATH, NUT_PIDPATH and NUT_ALTPIDPATH. And NUT_CONFPATH for config files, to mention them all. Try exporting these first 3 from the init scripts (consistently for all NUT components you run).
Thanks, those variables are very useful. Tweaking the entware scripts makes installing future entware package updates a pain. If there was a portable fix I would log an issue with entware so all entware NUT users would avoid the risk. Even a non-persistent upsmon.pid isn't a perfect solution.
For now I'll just keep my checkservices cron job hack which deletes upsmon.pid the next time it runs after the problem happens and notifies me. I might get lucky and never hit this issue again.
This is a apparently a bigger topic than this NUT issue.
Well, in case of NUT the PID files are also important for inter-process communications of sorts, such as sending signals to already-running daemons (e.g. to upsmon -c reload live). If a random process lives at that PID, for a majority of NUT programs that run as an unprivileged user like ups or nut it should end up as just inability to send the signal due to permissions. In this, upsmon may be special as it typically starts as root (so there's a piece with permission to shut down the host) and privileges are dropped for the majority of the program.
In the entware distribution of upsmon the -p argument is the only one used so everything is "all root all the time" so sending signals to a a random daemon will succeed. My router only has root so that's a rare case where -p makes sense.
Could an argument tell upsmon to run pidof from the OS to double check the PID rather than only consulting the PID file? The entware startup scripts use pidof before launching anything so they already assume all the platforms they support have pidof so entware might consider using such an option especially since using -p.
Just brainstorming crazy ideas on how to never confuse a random process for a NUT program. I'm no expert...
Adding a dependency on a random program is not a likely way forward. I'm tinkering to check with how ps programs on differrnt known OSes do it - so if we can get a name, check it...
Activity
jimklimov commentedon Jun 5, 2024
Thanks, that's an interesting case, although the hard part can be looking up the process name for a PID across many platforms that all do it differently.
Just in case: is the problem happening at router start-up? Does your build of NUT there store the PID files in a persistent storage location, or in a tmpfs that should be empty after a reboot?
Also, which version of NUT is involved? I think with recent ones, a graceful exit of the daemon should have it delete the PID file.
yoyoma2 commentedon Jun 6, 2024
These are the entware packages installed on the router so a pretty recent version.
The pid file is in /opt/var/run which is persistent. The /opt/etc/init.d/S15upsmon startup script isn't specifying a variable with the directory for the pid file so not sure how to override this to a non-persistent directory.
This problem only happened once after a non-graceful reboot of the router. I kept getting emails about upsmon not running so all subsequent attempts to start upsmon were also failing.
Since the entware startup scripts already perform a check of an already running process (below), perhaps a upsmon command-line argument to skip the redundant test at upsmon startup could be a workaround.
This is admittedly a fringe case that requires bad luck to occur.
jimklimov commentedon Jun 6, 2024
For temporary files (PID, Unix socket, etc.), NUT uses generally several locations which are built into the binaries by
configrescript settings, but can be customized by environment variables such asNUT_STATEPATH,NUT_PIDPATHandNUT_ALTPIDPATH. AndNUT_CONFPATHfor config files, to mention them all. Try exporting these first 3 from the init scripts (consistently for all NUT components you run).yoyoma2 commentedon Jun 6, 2024
Thanks, those variables are very useful. Tweaking the entware scripts makes installing future entware package updates a pain. If there was a portable fix I would log an issue with entware so all entware NUT users would avoid the risk. Even a non-persistent upsmon.pid isn't a perfect solution.
For now I'll just keep my checkservices cron job hack which deletes upsmon.pid the next time it runs after the problem happens and notifies me. I might get lucky and never hit this issue again.
This is a apparently a bigger topic than this NUT issue.
jimklimov commentedon Jun 7, 2024
Well, in case of NUT the PID files are also important for inter-process communications of sorts, such as sending signals to already-running daemons (e.g. to
upsmon -c reloadlive). If a random process lives at that PID, for a majority of NUT programs that run as an unprivileged user likeupsornutit should end up as just inability to send the signal due to permissions. In this,upsmonmay be special as it typically starts asroot(so there's a piece with permission to shut down the host) and privileges are dropped for the majority of the program.yoyoma2 commentedon Jun 7, 2024
In the entware distribution of upsmon the -p argument is the only one used so everything is "all root all the time" so sending signals to a a random daemon will succeed. My router only has root so that's a rare case where -p makes sense.
Could an argument tell upsmon to run pidof from the OS to double check the PID rather than only consulting the PID file? The entware startup scripts use pidof before launching anything so they already assume all the platforms they support have pidof so entware might consider using such an option especially since using -p.
Just brainstorming crazy ideas on how to never confuse a random process for a NUT program. I'm no expert...
jimklimov commentedon Jun 7, 2024
Adding a dependency on a random program is not a likely way forward. I'm tinkering to check with how
psprograms on differrnt known OSes do it - so if we can get a name, check it...37 remaining items
include/common.h, common/common.c: refactor apart compareprocname() f…
include/common.h, common/common.c: refactor apart checkprocname_ignor…
common/common.c: refactor sendsignalpid() to check checkprocname_igno…
common/common.c: compareprocname(): fix basename comparison (copy-pas…
common/common.c: compareprocname(): comment about libtool-wrapped dev…
Introduce getprocname() and checkprocname() for suspicious PID values…
Pass "progname" through sendsignal*() methods to verify that we sends…
common/common.c: getprocname(): implement support for /proc/NNN/cmdli…
common/common.c: getprocname(): implement support for /proc/NNN/stat …
common/common.c: getprocname(): implement support for (Open)BSD parsi…
common/common.c: getprocname(): revise printed messages [networkupsto…
common/common.c: getprocname(): implement support for /proc/NNN/psinf…
common/common.c: getprocname(): implement support for WIN32 parsing w…
common/common.c: checkprocname(): case networkupstools#5 is not "exac…