From cae9d585b1e4c87a803fd646a78d234b183507c4 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 10:39:38 +0000 Subject: [PATCH 01/15] include/common.h, common.c: extend sendsignalfn() return value for more error types --- common/common.c | 9 ++++++--- include/common.h | 8 +++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/common/common.c b/common/common.c index 472d15ecac..7cfd54cc6d 100644 --- a/common/common.c +++ b/common/common.c @@ -302,7 +302,10 @@ void writepid(const char *name) umask(mask); } -/* open pidfn, get the pid, then send it sig */ +/* open pidfn, get the pid, then send it sig + * returns negative codes for errors, or + * zero for a successfully sent signal + */ int sendsignalfn(const char *pidfn, int sig) { char buf[SMALLBUF]; @@ -313,13 +316,13 @@ int sendsignalfn(const char *pidfn, int sig) pidf = fopen(pidfn, "r"); if (!pidf) { upslog_with_errno(LOG_NOTICE, "fopen %s", pidfn); - return -1; + return -3; } if (fgets(buf, sizeof(buf), pidf) == NULL) { upslogx(LOG_NOTICE, "Failed to read pid from %s", pidfn); fclose(pidf); - return -1; + return -2; } { /* scoping */ diff --git a/include/common.h b/include/common.h index 67deaff905..66be3be4fa 100644 --- a/include/common.h +++ b/include/common.h @@ -112,7 +112,13 @@ int snprintfcat(char *dst, size_t size, const char *fmt, ...) /* Report maximum platform value for the pid_t */ pid_t get_max_pid_t(void); -/* open , get the pid, then send it */ +/* open , get the pid, then send it + * returns zero for successfully sent signal, + * negative for errors: + * -3 PID file not found + * -2 PID file not parsable + * -1 Error sending signal + */ int sendsignalfn(const char *pidfn, int sig); const char *xbasename(const char *file); From dfd955fd9c72c347c34ec8a0991d03e185c2d969 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 10:45:41 +0000 Subject: [PATCH 02/15] common/common.c: sendsignalfn(): if we use sig==0 to probe that a process runs, no need to send that twice --- common/common.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/common/common.c b/common/common.c index 7cfd54cc6d..e90279a193 100644 --- a/common/common.c +++ b/common/common.c @@ -349,13 +349,15 @@ int sendsignalfn(const char *pidfn, int sig) return -1; } - /* now actually send it */ - ret = kill(pid, sig); - - if (ret < 0) { - perror("kill"); - fclose(pidf); - return -1; + if (sig != 0) { + /* now actually send it */ + ret = kill(pid, sig); + + if (ret < 0) { + perror("kill"); + fclose(pidf); + return -1; + } } fclose(pidf); From 3c06eca39e17e5d770267d1b4ebb19fd53d89d78 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 10:48:29 +0000 Subject: [PATCH 03/15] server/upsd.c: handle extended return values from sendsignalfn() to tell more about the error --- server/upsd.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/server/upsd.c b/server/upsd.c index 68e7e7ba85..e53c1eb6bb 100644 --- a/server/upsd.c +++ b/server/upsd.c @@ -1341,10 +1341,26 @@ int main(int argc, char **argv) /* otherwise, we are being asked to start. * so check if a previous instance is running by sending signal '0' * (Ie 'kill 0') */ - if (sendsignalfn(pidfn, 0) == 0) { + cmdret = sendsignalfn(pidfn, 0); + switch (cmdret) { + case 0: printf("Fatal error: A previous upsd instance is already running!\n"); printf("Either stop the previous instance first, or use the 'reload' command.\n"); exit(EXIT_FAILURE); + + case -3: + case -2: + upslogx(LOG_WARNING, "Could not %s PID file '%s' " + "to see if previous upsd instance is " + "already running!\n", + (cmdret == -3 ? "find" : "parse"), + pidfn); + break; + + case -1: + default: + /* Just failed to send signal, no competitor running */ + break; } argc -= optind; From f04c0268db773c8cbea9c8efb0ba4cbadb2f79be Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 10:55:10 +0000 Subject: [PATCH 04/15] server/upsd.c: warn about not saving a pid file --- server/upsd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/server/upsd.c b/server/upsd.c index e53c1eb6bb..0eb6e7083f 100644 --- a/server/upsd.c +++ b/server/upsd.c @@ -1458,6 +1458,7 @@ int main(int argc, char **argv) background(); writepid(pidfn); } else { + upslogx(LOG_WARNING, "Running as foreground process, not saving a PID file"); memset(pidfn, 0, sizeof(pidfn)); } From b4f4f28557f82a0f8c7c0b7e018a60f040fd8d6f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 11:18:26 +0000 Subject: [PATCH 05/15] include/common.h, common.c: refactor sendsignalfn() into parsepid() and sendsignalpid() reusable methods --- common/common.c | 97 ++++++++++++++++++++++++++++++++---------------- include/common.h | 8 ++++ 2 files changed, 72 insertions(+), 33 deletions(-) diff --git a/common/common.c b/common/common.c index e90279a193..a1ed3a2c9c 100644 --- a/common/common.c +++ b/common/common.c @@ -302,41 +302,17 @@ void writepid(const char *name) umask(mask); } -/* open pidfn, get the pid, then send it sig - * returns negative codes for errors, or +/* send sig to pid, returns -1 for error, or * zero for a successfully sent signal */ -int sendsignalfn(const char *pidfn, int sig) +int sendsignalpid(pid_t pid, int sig) { - char buf[SMALLBUF]; - FILE *pidf; - pid_t pid = -1; int ret; - pidf = fopen(pidfn, "r"); - if (!pidf) { - upslog_with_errno(LOG_NOTICE, "fopen %s", pidfn); - return -3; - } - - if (fgets(buf, sizeof(buf), pidf) == NULL) { - upslogx(LOG_NOTICE, "Failed to read pid from %s", pidfn); - fclose(pidf); - return -2; - } - - { /* scoping */ - intmax_t _pid = strtol(buf, (char **)NULL, 10); /* assuming 10 digits for a long */ - if (_pid <= get_max_pid_t()) { - pid = (pid_t)_pid; - } else { - upslogx(LOG_NOTICE, "Received a pid number too big for a pid_t: %" PRIdMAX, _pid); - } - } - - if (pid < 2) { - upslogx(LOG_NOTICE, "Ignoring invalid pid number %" PRIdMAX, (intmax_t) pid); - fclose(pidf); + if (pid < 2 || pid > get_max_pid_t()) { + upslogx(LOG_NOTICE, + "Ignoring invalid pid number %" PRIdMAX, + (intmax_t) pid); return -1; } @@ -345,7 +321,6 @@ int sendsignalfn(const char *pidfn, int sig) if (ret < 0) { perror("kill"); - fclose(pidf); return -1; } @@ -355,15 +330,71 @@ int sendsignalfn(const char *pidfn, int sig) if (ret < 0) { perror("kill"); - fclose(pidf); return -1; } } - fclose(pidf); return 0; } +/* parses string buffer into a pid_t if it passes + * a few sanity checks; returns -1 on error + */ +pid_t parsepid(const char *buf) +{ + pid_t pid = -1; + + /* assuming 10 digits for a long */ + intmax_t _pid = strtol(buf, (char **)NULL, 10); + if (_pid <= get_max_pid_t()) { + pid = (pid_t)_pid; + } else { + upslogx(LOG_NOTICE, "Received a pid number too big for a pid_t: %" PRIdMAX, _pid); + } + + return pid; +} + +/* open pidfn, get the pid, then send it sig + * returns negative codes for errors, or + * zero for a successfully sent signal + */ +int sendsignalfn(const char *pidfn, int sig) +{ + char buf[SMALLBUF]; + FILE *pidf; + pid_t pid = -1; + int ret = -1; + + pidf = fopen(pidfn, "r"); + if (!pidf) { + upslog_with_errno(LOG_NOTICE, "fopen %s", pidfn); + return -3; + } + + if (fgets(buf, sizeof(buf), pidf) == NULL) { + upslogx(LOG_NOTICE, "Failed to read pid from %s", pidfn); + fclose(pidf); + return -2; + } + /* TOTHINK: Original code only closed pidf before + * exiting the method, on error or "normally". + * Why not here? Do we want an (exclusive?) hold + * on it while being active in the method? + */ + + /* this method actively reports errors, if any */ + pid = parsepid(buf); + + if (pid >= 0) { + /* this method actively reports errors, if any */ + ret = sendsignalpid(pid, sig); + } + + fclose(pidf); + return ret; +} + int snprintfcat(char *dst, size_t size, const char *fmt, ...) { va_list ap; diff --git a/include/common.h b/include/common.h index 66be3be4fa..7358faeec8 100644 --- a/include/common.h +++ b/include/common.h @@ -103,6 +103,10 @@ void chroot_start(const char *path); /* write a pid file - is a full pathname *or* just the program name */ void writepid(const char *name); +/* parses string buffer into a pid_t if it passes + * a few sanity checks; returns -1 on error */ +pid_t parsepid(const char *buf); + /* send a signal to another running process */ int sendsignal(const char *progname, int sig); @@ -112,6 +116,10 @@ int snprintfcat(char *dst, size_t size, const char *fmt, ...) /* Report maximum platform value for the pid_t */ pid_t get_max_pid_t(void); +/* send sig to pid after some sanity checks, returns + * -1 for error, or zero for a successfully sent signal */ +int sendsignalpid(pid_t pid, int sig); + /* open , get the pid, then send it * returns zero for successfully sent signal, * negative for errors: From 0f194029d9cc6b9fd274008c9bf043e3f4c6ae58 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 11:19:15 +0000 Subject: [PATCH 06/15] server/upsd.c: add "-P PID" arg for commands [for #1299] --- docs/man/upsd.txt | 5 +++++ server/upsd.c | 21 ++++++++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/man/upsd.txt b/docs/man/upsd.txt index 771668a688..e2524c1c90 100644 --- a/docs/man/upsd.txt +++ b/docs/man/upsd.txt @@ -43,6 +43,11 @@ are: *reload*;; reread configuration files *stop*;; stop process and exit +*-P* 'pid':: +Send the command signal above using specified PID number, rather than +consulting the PID file. This can help define service units which +start `upsd` as a foreground process so it does not create a PID file. + *-D*:: Raise the debugging level. upsd will run in the foreground by default, and will print information on stdout about the monitoring process. diff --git a/server/upsd.c b/server/upsd.c index 0eb6e7083f..8342d4bdff 100644 --- a/server/upsd.c +++ b/server/upsd.c @@ -1173,6 +1173,7 @@ static void help(const char *arg_progname) printf(" commands:\n"); printf(" - reload: reread configuration files\n"); printf(" - stop: stop process and exit\n"); + printf(" -P send the signal above to specified PID (bypassing PID file)\n"); printf(" -D raise debugging level (and stay foreground by default)\n"); printf(" -F stay foregrounded even if no debugging is enabled\n"); printf(" -B stay backgrounded even if debugging is bumped\n"); @@ -1251,6 +1252,7 @@ int main(int argc, char **argv) char *chroot_path = NULL; const char *user = RUN_AS_USER; struct passwd *new_uid = NULL; + pid_t oldpid = -1; progname = xbasename(argv[0]); @@ -1263,7 +1265,7 @@ int main(int argc, char **argv) printf("Network UPS Tools %s %s\n", progname, UPS_VERSION); - while ((i = getopt(argc, argv, "+h46p:qr:i:fu:Vc:DFB")) != -1) { + while ((i = getopt(argc, argv, "+h46p:qr:i:fu:Vc:P:DFB")) != -1) { switch (i) { case 'p': case 'i': @@ -1301,6 +1303,11 @@ int main(int argc, char **argv) help(progname); break; + case 'P': + if ((oldpid = parsepid(optarg)) < 0) + help(progname); + break; + case 'D': nut_debug_level++; break; @@ -1334,14 +1341,22 @@ int main(int argc, char **argv) } if (cmd) { - cmdret = sendsignalfn(pidfn, cmd); + if (oldpid < 0) { + cmdret = sendsignalfn(pidfn, cmd); + } else { + cmdret = sendsignalpid(oldpid, cmd); + } exit((cmdret == 0)?EXIT_SUCCESS:EXIT_FAILURE); } /* otherwise, we are being asked to start. * so check if a previous instance is running by sending signal '0' * (Ie 'kill 0') */ - cmdret = sendsignalfn(pidfn, 0); + if (oldpid < 0) { + cmdret = sendsignalfn(pidfn, 0); + } else { + cmdret = sendsignalpid(oldpid, 0); + } switch (cmdret) { case 0: printf("Fatal error: A previous upsd instance is already running!\n"); From 9af2a4feb10b57f575c4483dfe28e96674e14221 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 11:37:40 +0000 Subject: [PATCH 07/15] upsd.c: add -FF option to stay foregrounded AND write the PID file, use it in systemd/nut-server.service [for #1299] --- docs/man/upsd.txt | 2 ++ scripts/systemd/nut-server.service.in | 2 +- server/upsd.c | 17 ++++++++++++++--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/docs/man/upsd.txt b/docs/man/upsd.txt index e2524c1c90..3dc2aebcf3 100644 --- a/docs/man/upsd.txt +++ b/docs/man/upsd.txt @@ -47,6 +47,7 @@ are: Send the command signal above using specified PID number, rather than consulting the PID file. This can help define service units which start `upsd` as a foreground process so it does not create a PID file. +See also `-FF` option as an alternative. *-D*:: Raise the debugging level. upsd will run in the foreground by default, @@ -55,6 +56,7 @@ Use this option multiple times for more details. *-F*:: upsd will run in the foreground, regardless of debugging settings. +Specify twice (`-FF` or `-F -F`) to save the PID file even in this mode. *-B*:: upsd will run in the background, regardless of debugging settings. diff --git a/scripts/systemd/nut-server.service.in b/scripts/systemd/nut-server.service.in index 0ad8a5e092..15d54f7585 100644 --- a/scripts/systemd/nut-server.service.in +++ b/scripts/systemd/nut-server.service.in @@ -20,7 +20,7 @@ PartOf=nut.target [Service] EnvironmentFile=-@CONFPATH@/nut.conf SyslogIdentifier=%N -ExecStart=@SBINDIR@/upsd -F +ExecStart=@SBINDIR@/upsd -FF ExecReload=@SBINDIR@/upsd -c reload [Install] diff --git a/server/upsd.c b/server/upsd.c index 8342d4bdff..4a709aa8c1 100644 --- a/server/upsd.c +++ b/server/upsd.c @@ -1176,6 +1176,7 @@ static void help(const char *arg_progname) printf(" -P send the signal above to specified PID (bypassing PID file)\n"); printf(" -D raise debugging level (and stay foreground by default)\n"); printf(" -F stay foregrounded even if no debugging is enabled\n"); + printf(" -FF stay foregrounded and still save the PID file\n"); printf(" -B stay backgrounded even if debugging is bumped\n"); printf(" -h display this help\n"); printf(" -r chroots to \n"); @@ -1312,7 +1313,12 @@ int main(int argc, char **argv) nut_debug_level++; break; case 'F': - foreground = 1; + if (foreground > 0) { + /* specified twice to save PID file anyway */ + foreground = 2; + } else { + foreground = 1; + } break; case 'B': foreground = 0; @@ -1473,8 +1479,13 @@ int main(int argc, char **argv) background(); writepid(pidfn); } else { - upslogx(LOG_WARNING, "Running as foreground process, not saving a PID file"); - memset(pidfn, 0, sizeof(pidfn)); + if (foreground == 2) { + upslogx(LOG_WARNING, "Running as foreground process, but saving a PID file anyway"); + writepid(pidfn); + } else { + upslogx(LOG_WARNING, "Running as foreground process, not saving a PID file"); + memset(pidfn, 0, sizeof(pidfn)); + } } /* initialize SSL (keyfile must be readable by nut user) */ From 35ea592a88ce4ea09ba041219ac6ecf3a27358f4 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 11:59:44 +0000 Subject: [PATCH 08/15] clients/upsmon.c: add "-P pid" arg handling, and report result of sendsignal(), like in upsd [for #1299, #123] --- clients/upsmon.c | 42 +++++++++++++++++++++++++++++++++++++----- docs/man/upsmon.txt | 8 +++++++- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/clients/upsmon.c b/clients/upsmon.c index 941b36d3b0..430258cd77 100644 --- a/clients/upsmon.c +++ b/clients/upsmon.c @@ -1809,6 +1809,7 @@ static void help(const char *arg_progname) printf(" - fsd: shutdown all primary-mode UPSes (use with caution)\n"); printf(" - reload: reread configuration\n"); printf(" - stop: stop monitoring and exit\n"); + printf(" -P send the signal above to specified PID (bypassing PID file)\n"); printf(" -D raise debugging level (and stay foreground by default)\n"); printf(" -F stay foregrounded even if no debugging is enabled\n"); printf(" -B stay backgrounded even if debugging is bumped\n"); @@ -2042,7 +2043,8 @@ static void check_parent(void) int main(int argc, char *argv[]) { const char *prog = xbasename(argv[0]); - int i, cmd = 0, checking_flag = 0, foreground = -1; + int i, cmd = 0, cmdret = -1, checking_flag = 0, foreground = -1; + pid_t oldpid = -1; printf("Network UPS Tools %s %s\n", prog, UPS_VERSION); @@ -2053,7 +2055,7 @@ int main(int argc, char *argv[]) run_as_user = xstrdup(RUN_AS_USER); - while ((i = getopt(argc, argv, "+DFBhic:f:pu:VK46")) != -1) { + while ((i = getopt(argc, argv, "+DFBhic:P:f:pu:VK46")) != -1) { switch (i) { case 'c': if (!strncmp(optarg, "fsd", strlen(optarg))) @@ -2067,6 +2069,12 @@ int main(int argc, char *argv[]) if (cmd == 0) help(argv[0]); break; + + case 'P': + if ((oldpid = parsepid(optarg)) < 0) + help(argv[0]); + break; + case 'D': nut_debug_level++; break; @@ -2121,17 +2129,41 @@ int main(int argc, char *argv[]) } if (cmd) { - sendsignal(prog, cmd); - exit(EXIT_SUCCESS); + if (oldpid < 0) { + cmdret = sendsignal(prog, cmd); + } else { + cmdret = sendsignalpid(oldpid, cmd); + } + /* exit(EXIT_SUCCESS); */ + exit((cmdret == 0)?EXIT_SUCCESS:EXIT_FAILURE); } /* otherwise, we are being asked to start. * so check if a previous instance is running by sending signal '0' * (Ie 'kill 0') */ - if (sendsignal(prog, 0) == 0) { + if (oldpid < 0) { + cmdret = sendsignal(prog, 0); + } else { + cmdret = sendsignalpid(oldpid, 0); + } + switch (cmdret) { + case 0: printf("Fatal error: A previous upsmon instance is already running!\n"); printf("Either stop the previous instance first, or use the 'reload' command.\n"); exit(EXIT_FAILURE); + + case -3: + case -2: + upslogx(LOG_WARNING, "Could not %s PID file " + "to see if previous upsmon instance is " + "already running!\n", + (cmdret == -3 ? "find" : "parse")); + break; + + case -1: + default: + /* Just failed to send signal, no competitor running */ + break; } argc -= optind; diff --git a/docs/man/upsmon.txt b/docs/man/upsmon.txt index 5006d40e49..2f226d5f42 100644 --- a/docs/man/upsmon.txt +++ b/docs/man/upsmon.txt @@ -11,7 +11,7 @@ SYNOPSIS *upsmon* -h -*upsmon* -c 'command' +*upsmon* -c 'command' [-P 'pid'] *upsmon* [-D] [-F | -B] [-K] [-p] [-u 'user'] @@ -44,6 +44,12 @@ commands are: *reload*;; reread linkman:upsmon.conf[5] configuration file. See "reloading nuances" below if this doesn't work. +*-P* 'pid':: +Send the command signal above using specified PID number, rather than +consulting the PID file. This can help define service units which +start main `upsmon` as a foreground process so it does not have to +rely on a PID file. + *-D*:: Raise the debugging level. upsmon will run in the foreground by default, and will print information on stdout about the monitoring process. From 1afbd2b010e45b5e7be99e6eca5693dfceebcb56 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 13:45:10 +0000 Subject: [PATCH 09/15] server/conf.c: allow upsd to reload config and apply its debug_min setting --- server/conf.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/server/conf.c b/server/conf.c index de973bdc1c..8bb694e1a8 100644 --- a/server/conf.c +++ b/server/conf.c @@ -333,6 +333,13 @@ void load_upsdconf(int reloading) return; } + if (reloading) { + /* if upsd.conf added or changed + * (or commented away) the debug_min + * setting, detect that */ + nut_debug_level_global = -1; + } + while (pconf_file_next(&ctx)) { if (pconf_parse_error(&ctx)) { upslogx(LOG_ERR, "Parse error: %s:%d: %s", @@ -359,6 +366,15 @@ void load_upsdconf(int reloading) } + if (reloading) { + if (nut_debug_level_global > -1) { + upslogx(LOG_INFO, + "Applying debug_min=%d from upsd.conf", + nut_debug_level_global); + nut_debug_level = nut_debug_level_global; + } + } + pconf_finish(&ctx); } From 1bdc4fbb685a07fc0033d3abed6ebb856369e739 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 13:46:27 +0000 Subject: [PATCH 10/15] scripts/systemd/nut-server.service.in: reload upsd without PID file [for #1299] --- scripts/systemd/nut-server.service.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/systemd/nut-server.service.in b/scripts/systemd/nut-server.service.in index 15d54f7585..713f5c4273 100644 --- a/scripts/systemd/nut-server.service.in +++ b/scripts/systemd/nut-server.service.in @@ -20,8 +20,10 @@ PartOf=nut.target [Service] EnvironmentFile=-@CONFPATH@/nut.conf SyslogIdentifier=%N -ExecStart=@SBINDIR@/upsd -FF -ExecReload=@SBINDIR@/upsd -c reload +# Note: foreground mode by default skips writing a PID file (and +# needs Type=simple); can use "-FF" here to create one anyway: +ExecStart=@SBINDIR@/upsd -F +ExecReload=@SBINDIR@/upsd -c reload -P $MAINPID [Install] WantedBy=nut.target From db56595493f8d844d76bb39c5daf4854b3d2f3ed Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 15:19:44 +0100 Subject: [PATCH 11/15] common/common.c: writepid(): debug-trace creation of a PID file --- common/common.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/common/common.c b/common/common.c index a1ed3a2c9c..bb00aafdc9 100644 --- a/common/common.c +++ b/common/common.c @@ -293,7 +293,9 @@ void writepid(const char *name) pidf = fopen(fn, "w"); if (pidf) { - fprintf(pidf, "%d\n", (int) getpid()); + intmax_t pid = (intmax_t)getpid(); + upsdebugx(1, "Saving PID %jd into %s", pid, fn); + fprintf(pidf, "%jd\n", pid); fclose(pidf); } else { upslog_with_errno(LOG_NOTICE, "writepid: fopen %s", fn); From fcb8b5ef9cf00705782dcdcabd1500ac0efb46d1 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 15:50:52 +0100 Subject: [PATCH 12/15] clients/upsmon.c: allow upsmon to reload config and apply its debug_min setting --- clients/upsmon.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clients/upsmon.c b/clients/upsmon.c index 430258cd77..174099c24e 100644 --- a/clients/upsmon.c +++ b/clients/upsmon.c @@ -1977,9 +1977,21 @@ static void reload_conf(void) /* reset paranoia checker */ totalpv = 0; + /* if upsmon.conf added or changed + * (or commented away) the debug_min + * setting, detect that */ + nut_debug_level_global = -1; + /* reread upsmon.conf */ loadconfig(); + if (nut_debug_level_global > -1) { + upslogx(LOG_INFO, + "Applying debug_min=%d from upsmon.conf", + nut_debug_level_global); + nut_debug_level = nut_debug_level_global; + } + /* go through the utype_t struct again */ tmp = firstups; From fccbc771fe134b03ac5cefe8376ce62fcdd0bd6f Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 15:12:43 +0000 Subject: [PATCH 13/15] clients/upsmon.c: whitespace fix --- clients/upsmon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/upsmon.c b/clients/upsmon.c index 174099c24e..66a3eaf367 100644 --- a/clients/upsmon.c +++ b/clients/upsmon.c @@ -1279,7 +1279,7 @@ static int parse_conf_arg(size_t numargs, char **arg) } /* RUN_AS_USER */ - if (!strcmp(arg[0], "RUN_AS_USER")) { + if (!strcmp(arg[0], "RUN_AS_USER")) { free(run_as_user); run_as_user = xstrdup(arg[1]); return 1; From 7115eb1e846ac3297891e5e9dfdd4ccdd75d3c97 Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 15:13:11 +0000 Subject: [PATCH 14/15] clients/upsmon.c: restructure config reload for debug_min to be more similar to that in upsd.c --- clients/upsmon.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/clients/upsmon.c b/clients/upsmon.c index 66a3eaf367..ab0245ffe1 100644 --- a/clients/upsmon.c +++ b/clients/upsmon.c @@ -1393,6 +1393,13 @@ static void loadconfig(void) fatalx(EXIT_FAILURE, "%s", ctx.errmsg); } + if (reload_flag == 1) { + /* if upsmon.conf added or changed + * (or commented away) the debug_min + * setting, detect that */ + nut_debug_level_global = -1; + } + while (pconf_file_next(&ctx)) { if (pconf_parse_error(&ctx)) { upslogx(LOG_ERR, "Parse error: %s:%d: %s", @@ -1419,6 +1426,15 @@ static void loadconfig(void) } } + if (reload_flag == 1) { + if (nut_debug_level_global > -1) { + upslogx(LOG_INFO, + "Applying debug_min=%d from upsmon.conf", + nut_debug_level_global); + nut_debug_level = nut_debug_level_global; + } + } + pconf_finish(&ctx); } @@ -1977,21 +1993,9 @@ static void reload_conf(void) /* reset paranoia checker */ totalpv = 0; - /* if upsmon.conf added or changed - * (or commented away) the debug_min - * setting, detect that */ - nut_debug_level_global = -1; - /* reread upsmon.conf */ loadconfig(); - if (nut_debug_level_global > -1) { - upslogx(LOG_INFO, - "Applying debug_min=%d from upsmon.conf", - nut_debug_level_global); - nut_debug_level = nut_debug_level_global; - } - /* go through the utype_t struct again */ tmp = firstups; From aae4fe6e39f4eb09cd81084c76253f9a7c09a2cc Mon Sep 17 00:00:00 2001 From: Jim Klimov Date: Wed, 16 Feb 2022 16:43:27 +0100 Subject: [PATCH 15/15] upsd and upsmon configuration sample files and man pages: add note about run-time config reload with DEBUG_MIN setting in sight --- conf/upsd.conf.sample | 11 +++++++++++ conf/upsmon.conf.sample.in | 11 +++++++++++ docs/man/upsd.conf.txt | 11 +++++++++++ docs/man/upsmon.conf.txt | 11 +++++++++++ 4 files changed, 44 insertions(+) diff --git a/conf/upsd.conf.sample b/conf/upsd.conf.sample index 9d6a9cd1f4..fb420e3a78 100644 --- a/conf/upsd.conf.sample +++ b/conf/upsd.conf.sample @@ -155,3 +155,14 @@ # running mode directly, and without need to edit init-scripts or service # unit definitions. Note that command-line option `-D` can only increase # this verbosity level. +# +# NOTE: if the running daemon receives a `reload` command, presence of the +# `DEBUG_MIN NUMBER` value in the configuration file can be used to tune +# debugging verbosity in the running service daemon (it is recommended to +# comment it away or set the minimum to explicit zero when done, to avoid +# huge journals and I/O system abuse). Keep in mind that for this run-time +# tuning, the `DEBUG_MIN` value *present* in *reloaded* configuration files +# is applied instantly and overrides any previously set value, from file +# or CLI options, regardless of older logging level being higher or lower +# than the newly found number; a missing (or commented away) value however +# does not change the previously active logging verbosity. diff --git a/conf/upsmon.conf.sample.in b/conf/upsmon.conf.sample.in index dedbb92afb..aeec849eda 100644 --- a/conf/upsmon.conf.sample.in +++ b/conf/upsmon.conf.sample.in @@ -440,3 +440,14 @@ FINALDELAY 5 # running mode directly, and without need to edit init-scripts or service # unit definitions. Note that command-line option `-D` can only increase # this verbosity level. +# +# NOTE: if the running daemon receives a `reload` command, presence of the +# `DEBUG_MIN NUMBER` value in the configuration file can be used to tune +# debugging verbosity in the running service daemon (it is recommended to +# comment it away or set the minimum to explicit zero when done, to avoid +# huge journals and I/O system abuse). Keep in mind that for this run-time +# tuning, the `DEBUG_MIN` value *present* in *reloaded* configuration files +# is applied instantly and overrides any previously set value, from file +# or CLI options, regardless of older logging level being higher or lower +# than the newly found number; a missing (or commented away) value however +# does not change the previously active logging verbosity. diff --git a/docs/man/upsd.conf.txt b/docs/man/upsd.conf.txt index 40f9786a5d..67e41dbf46 100644 --- a/docs/man/upsd.conf.txt +++ b/docs/man/upsd.conf.txt @@ -135,6 +135,17 @@ Optionally specify a minimum debug level for `upsd` data daemon, e.g. for troubleshooting a deployment, without impacting foreground or background running mode directly. Command-line option `-D` can only increase this verbosity level. ++ +NOTE: if the running daemon receives a `reload` command, presence of the +`DEBUG_MIN NUMBER` value in the configuration file can be used to tune +debugging verbosity in the running service daemon (it is recommended to +comment it away or set the minimum to explicit zero when done, to avoid +huge journals and I/O system abuse). Keep in mind that for this run-time +tuning, the `DEBUG_MIN` value *present* in *reloaded* configuration files +is applied instantly and overrides any previously set value, from file +or CLI options, regardless of older logging level being higher or lower +than the newly found number; a missing (or commented away) value however +does not change the previously active logging verbosity. SEE ALSO -------- diff --git a/docs/man/upsmon.conf.txt b/docs/man/upsmon.conf.txt index ac92401a60..8aa44443cc 100644 --- a/docs/man/upsmon.conf.txt +++ b/docs/man/upsmon.conf.txt @@ -399,6 +399,17 @@ Optionally specify a minimum debug level for `upsmon` daemon, e.g. for troubleshooting a deployment, without impacting foreground or background running mode directly. Command-line option `-D` can only increase this verbosity level. ++ +NOTE: if the running daemon receives a `reload` command, presence of the +`DEBUG_MIN NUMBER` value in the configuration file can be used to tune +debugging verbosity in the running service daemon (it is recommended to +comment it away or set the minimum to explicit zero when done, to avoid +huge journals and I/O system abuse). Keep in mind that for this run-time +tuning, the `DEBUG_MIN` value *present* in *reloaded* configuration files +is applied instantly and overrides any previously set value, from file +or CLI options, regardless of older logging level being higher or lower +than the newly found number; a missing (or commented away) value however +does not change the previously active logging verbosity. SEE ALSO --------