Skip to content

Commit 52ce507

Browse files
authored
Merge 942d180 into 8d5e543
2 parents 8d5e543 + 942d180 commit 52ce507

2 files changed

Lines changed: 80 additions & 20 deletions

File tree

NEWS.adoc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ https://github.com/networkupstools/nut/milestone/12
5656
* Updated `help()` and failure messages to suggest `-m '*,-'` for logging
5757
of all known local devices to stdout. [#3083]
5858

59+
- `upsmon` client updates:
60+
* The `SHUTDOWNEXIT` option was not handled properly, and the requested
61+
long delays did not happen in practice. [issues #2133 and #3084, PR #3086]
62+
5963
- `configure` script options:
6064
* Introduced `--with-python{,2,3}-modules-dir` to specify PyNUT(Client)
6165
module installation location (for module-named dir to be created under

clients/upsmon.c

Lines changed: 76 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ static int nut_debug_level_args = 0;
184184

185185
/* pre-declare internal methods */
186186
static int get_var(utype_t *ups, const char *var, char *buf, size_t bufsize);
187+
static void set_alarm(void);
188+
static void clear_alarm(void);
187189

188190
static void setflag(int *val, int flag)
189191
{
@@ -993,28 +995,63 @@ static void doshutdown(void)
993995
shutdowncmd);
994996
}
995997

998+
upsdebugx(1, "%s: current exit_flag=%i", __func__, exit_flag);
996999
if (shutdownexitdelay == 0) {
9971000
upsdebugx(1,
9981001
"Exiting upsmon immediately "
9991002
"after initiating shutdown, by default");
1000-
} else
1001-
if (shutdownexitdelay < 0) {
1002-
upslogx(LOG_WARNING,
1003-
"Configured to not exit upsmon "
1004-
"after initiating shutdown");
1005-
/* Technically, here we sleep until SIGTERM or poweroff */
1006-
do {
1007-
sleep(1);
1008-
} while (!exit_flag);
10091003
} else {
1010-
upslogx(LOG_WARNING,
1011-
"Configured to only exit upsmon %d sec "
1012-
"after initiating shutdown", shutdownexitdelay);
1004+
if (shutdownexitdelay < 0) {
1005+
upslogx(LOG_WARNING,
1006+
"Configured to not exit upsmon "
1007+
"after initiating shutdown");
1008+
} else {
1009+
upslogx(LOG_WARNING,
1010+
"Configured to only exit upsmon %d sec "
1011+
"after initiating shutdown", shutdownexitdelay);
1012+
}
1013+
if (exit_flag) {
1014+
/* TOTHINK: Are there cases when we want to
1015+
* ignore it? Or is a SIGTERM, SIGBRK etc.
1016+
* a good enough reason to do exit quickly? */
1017+
upslogx(LOG_WARNING,
1018+
"Note that 'exit_flag' was raised by a "
1019+
"signal, so this process will not in fact "
1020+
"wait that long");
1021+
}
1022+
1023+
/* Technically, here we sleep until SIGTERM or poweroff,
1024+
* or in case of initially positive shutdownexitdelay --
1025+
* when it counts down to zero.
1026+
*/
10131027
do {
1028+
utype_t *ups;
1029+
char temp[SMALLBUF];
1030+
long maxlogins = 0, logins = 0;
1031+
1032+
/* Contact the data server(s) regularly so this
1033+
* client is not assumed dead while looping */
1034+
for (ups = firstups; ups != NULL && !exit_flag; ups = ups->next) {
1035+
set_alarm();
1036+
1037+
if (get_var(ups, "numlogins", temp, sizeof(temp)) >= 0) {
1038+
logins = strtol(temp, (char **)NULL, 10);
1039+
1040+
if (logins > maxlogins)
1041+
maxlogins = logins;
1042+
}
1043+
1044+
clear_alarm();
1045+
}
1046+
1047+
if (shutdownexitdelay > 0)
1048+
shutdownexitdelay--;
10141049
sleep(1);
1015-
shutdownexitdelay--;
1016-
} while (!exit_flag && shutdownexitdelay);
1050+
} while (!exit_flag && shutdownexitdelay != 0);
10171051
}
1052+
1053+
upsdebugx(1, "%s: current exit_flag=%i", __func__, exit_flag);
1054+
upslogx(LOG_WARNING, "Exiting upsmon program after initiating shutdown");
10181055
exit(EXIT_SUCCESS);
10191056
}
10201057

@@ -1573,8 +1610,14 @@ static void recalc(void)
15731610
upsdebugx(3, "Current power value: %u", val_ol);
15741611
upsdebugx(3, "Minimum power value: %u", minsupplies);
15751612

1576-
if (val_ol < minsupplies)
1613+
/* Note that a monitoring-only upsmon instance would have MINSUPPLIES 0
1614+
* and so would never see a smaller amount of healthily online UPSes */
1615+
if (val_ol < minsupplies) {
1616+
upslogx(LOG_WARNING, "Too few UPS(es) are healthy (%u<%u), "
1617+
"initiating forced shutdown",
1618+
val_ol, minsupplies);
15771619
forceshutdown();
1620+
}
15781621
}
15791622

15801623
static void ups_low_batt(utype_t *ups)
@@ -2542,6 +2585,7 @@ static void sigpipe(int sig)
25422585
/* SIGQUIT, SIGTERM handler */
25432586
static void set_exit_flag(int sig)
25442587
{
2588+
upslogx(LOG_INFO, "Signal %d: User requested EXIT", sig);
25452589
exit_flag = sig;
25462590
}
25472591

@@ -2610,6 +2654,7 @@ static void set_reload_flag(int sig)
26102654
{
26112655
NUT_UNUSED_VARIABLE(sig);
26122656

2657+
upslogx(LOG_INFO, "Signal %d: User requested RELOAD", sig);
26132658
reload_flag = 1;
26142659
}
26152660

@@ -3181,7 +3226,8 @@ static void clear_pdflag(void)
31813226
unlink(powerdownflag);
31823227
}
31833228

3184-
/* exit with success only if it exists and is proper */
3229+
/* exit with success only if the POWERDOWNFLAG file is configured,
3230+
* exists and has proper contents */
31853231
static int check_pdflag(void)
31863232
{
31873233
int ret;
@@ -3314,10 +3360,13 @@ static void runparent(int fd)
33143360
sret = system(shutdowncmd);
33153361

33163362
if (sret != 0)
3317-
upslogx(LOG_ERR, "parent: Unable to call shutdown command: %s",
3363+
upslogx(LOG_ERR, "upsmon parent: Unable to call shutdown command: %s",
33183364
shutdowncmd);
33193365

33203366
close(fd);
3367+
upslogx(LOG_WARNING, "upsmon parent: Exiting after %s (%i) shutdown command: %s",
3368+
(sret == 0 ? "calling" : "trying to call"),
3369+
sret, shutdowncmd);
33213370
exit(EXIT_SUCCESS);
33223371
}
33233372
#endif /* !WIN32 */
@@ -3792,6 +3841,9 @@ int main(int argc, char *argv[])
37923841
#endif /* not WIN32 */
37933842
}
37943843

3844+
upslogx(LOG_WARNING, "Exiting upsmon instance after sending "
3845+
"a signal to the running daemon %ssuccessfully",
3846+
(cmdret == 0 ? "" : "un"));
37953847
exit((cmdret == 0) ? EXIT_SUCCESS : EXIT_FAILURE);
37963848
}
37973849

@@ -3910,8 +3962,10 @@ int main(int argc, char *argv[])
39103962
upsnotify(NOTIFY_STATE_WATCHDOG, NULL);
39113963

39123964
/* check flags from signal handlers */
3913-
if (userfsd)
3965+
if (userfsd) {
3966+
upslogx(LOG_WARNING, "Got an FSD signal, initiating forced shutdown");
39143967
forceshutdown();
3968+
}
39153969

39163970
if (reload_flag) {
39173971
upsnotify(NOTIFY_STATE_RELOADING, NULL);
@@ -3967,8 +4021,10 @@ int main(int argc, char *argv[])
39674021
upsnotify(NOTIFY_STATE_READY, NULL);
39684022
upsnotify(NOTIFY_STATE_WATCHDOG, NULL);
39694023

3970-
if (exit_flag)
4024+
if (exit_flag) {
4025+
upslogx(LOG_WARNING, "%s: OS was last known to be preparing for sleep, and we have the exit_flag raised now", prog);
39714026
break;
4027+
}
39724028

39734029
if (reload_flag && sleep_inhibitor_status != 0) {
39744030
upslogx(LOG_WARNING, "%s: OS was last known to be preparing for sleep, and we were "
@@ -4115,7 +4171,7 @@ int main(int argc, char *argv[])
41154171
sleepval, difftimeval(end, start));
41164172

41174173
if (ret == WAIT_FAILED) {
4118-
upslogx(LOG_ERR, "Wait failed");
4174+
upslogx(LOG_ERR, "%s: Wait between main loop cycles failed", prog);
41194175
exit(EXIT_FAILURE);
41204176
}
41214177

0 commit comments

Comments
 (0)