FreeBSD Bugzilla – Attachment 236051 Details for
Bug 265963
sysutils/nut: add possibility to log status of several UPSes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Add script as a sample
0001-sysutils-nut-Add-upslog-support-for-multiple-UPSs.patch (text/plain), 15.23 KB, created by
Cy Schubert
on 2022-08-21 18:29:04 UTC
(
hide
)
Description:
Add script as a sample
Filename:
MIME Type:
Creator:
Cy Schubert
Created:
2022-08-21 18:29:04 UTC
Size:
15.23 KB
patch
obsolete
>From 336b121d122b2a8c61b099e66ead950949439521 Mon Sep 17 00:00:00 2001 >From: Cy Schubert <cy@FreeBSD.org> >Date: Sun, 21 Aug 2022 08:21:51 -0700 >Subject: [PATCH] sysutils/nut*: Add upslog support for multiple UPSs > >upslog is a utility that logs UPS status at regular intervals, specified >by the -i option. Unfortunately upslog supports only on UPS. For sites >that need to monitor multiple UPSs the options are to cobble an rc script >for each or doctor up the nut_upslog.in script to support cloning of the >script. Unfortunately an rc script capable of being cloned would become >the source of more PRs and would require significanly more tehcnical >documentation that by itself might become confusing for the average >system administrator. > >Therefore a new -m option is added to support multiple UPSs using the >same invocation of upslog. The patch parses a -m option and forks >almost immediately following the getopt(3) invokation to monitor each >individual UPS using a separate upslog process. This is not ideal but >better than scripting. Lightweight threads might be a better solution. > >The second add to nut is a sample rc script which performs the same >function as the the patch to upslog for those who prefer to create >individual rc scripts for each ups. The sample rc script was provided >by vvd@unislabs.com. > >PR: 265963 >Reported by: vvd@unislabs.com >--- > sysutils/nut-devel/Makefile | 1 + > sysutils/nut-devel/files/nut_upslog.sample | 52 +++++++ > .../nut-devel/files/patch-clients_upslog.c | 133 ++++++++++++++++++ > sysutils/nut-devel/pkg-plist | 1 + > sysutils/nut/Makefile | 2 +- > sysutils/nut/files/nut_upslog.sample | 52 +++++++ > sysutils/nut/files/patch-clients_upslog.c | 133 ++++++++++++++++++ > sysutils/nut/pkg-plist | 1 + > 8 files changed, 374 insertions(+), 1 deletion(-) > create mode 100644 sysutils/nut-devel/files/nut_upslog.sample > create mode 100644 sysutils/nut-devel/files/patch-clients_upslog.c > create mode 100644 sysutils/nut/files/nut_upslog.sample > create mode 100644 sysutils/nut/files/patch-clients_upslog.c > >diff --git a/sysutils/nut-devel/Makefile b/sysutils/nut-devel/Makefile >index 9e30974d0999..e40b38582e55 100644 >--- a/sysutils/nut-devel/Makefile >+++ b/sysutils/nut-devel/Makefile >@@ -1,5 +1,6 @@ > PORTNAME= nut > PORTVERSION= ${NUT_COMMIT_DATE} >+PORTREVISION= 1 > CATEGORIES= sysutils > PKGNAMESUFFIX= -devel > # MASTER_SITES= http://www.networkupstools.org/source/${PORTVERSION:R}/ >diff --git a/sysutils/nut-devel/files/nut_upslog.sample b/sysutils/nut-devel/files/nut_upslog.sample >new file mode 100644 >index 000000000000..126a47a70d3a >--- /dev/null >+++ b/sysutils/nut-devel/files/nut_upslog.sample >@@ -0,0 +1,52 @@ >+#!/bin/sh >+ >+# Authored by vvd@unislabs.com. >+ >+# PROVIDE: nut_upslog >+# REQUIRE: NETWORKING nut >+# BEFORE: LOGIN >+# KEYWORD: shutdown >+ >+. /etc/rc.subr >+ >+case $0 in >+/etc/rc*) >+ # during boot (shutdown) $0 is /etc/rc (/etc/rc.shutdown), >+ # so get the name of the script from $_file >+ name=$_file >+ ;; >+*) >+ name=$0 >+ ;; >+esac >+ >+name=${name##*/} >+rcvar=${name}_enable >+ >+load_rc_config "${name}" >+ >+# Define these nut_upslog* variables in one of these files: >+# /etc/rc.conf >+# /etc/rc.conf.local >+# /etc/rc.conf.d/nut_upslog >+# >+# If you want to log several different UPSes: >+# ln -s nut_upslog /usr/local/etc/rc.d/NAME >+# then set variables NAME_enable, NAME_ups, NAME_pidbase, NAME_logfile and etc. >+# >+# DO NOT CHANGE THESE DEFAULT VALUES HERE >+# >+eval "${rcvar}=\${${rcvar}:-'NO'}" >+eval "_prefix=\${${name}_prefix:-'/usr/local'}" >+eval "_logfile=\${${name}_logfile:-'/var/log/nut/ups.log'}" >+eval "_interval=\${${name}_interval:-'300'}" >+eval "_ups=\${${name}_ups:-'myups@localhost'}" >+eval "_pidbase=\${${name}_pidbase:-'upslog'}" >+eval "_format=\${${name}_format:+-f \${${name}_format}}" >+eval "${name}_flags=\${${name}_flags:-'-s ${_ups} -l ${_logfile} -i ${_interval} -p ${_pidbase} ${_format}'}" >+ >+required_dirs="%%STATEDIR%%" >+pidfile="%%STATEDIR%%/${_pidbase}.pid" >+command="${_prefix}/bin/upslog" >+ >+run_rc_command "$1" >diff --git a/sysutils/nut-devel/files/patch-clients_upslog.c b/sysutils/nut-devel/files/patch-clients_upslog.c >new file mode 100644 >index 000000000000..699abd785325 >--- /dev/null >+++ b/sysutils/nut-devel/files/patch-clients_upslog.c >@@ -0,0 +1,133 @@ >+--- clients/upslog.c.orig 2022-08-21 09:28:11.630024000 -0700 >++++ clients/upslog.c 2022-08-21 10:23:05.691271000 -0700 >+@@ -32,6 +32,10 @@ >+ */ >+ >+ #include "common.h" >++#include <signal.h> >++#include <unistd.h> >++#include <sys/types.h> >++#include <sys/wait.h> >+ #include "nut_platform.h" >+ #include "upsclient.h" >+ >+@@ -41,17 +45,32 @@ >+ #include "upslog.h" >+ >+ static int reopen_flag = 0, exit_flag = 0; >++ static int wait_status, child_pid; >+ static uint16_t port; >+ static char *upsname, *hostname; >+ static UPSCONN_t ups; >+ >+ static FILE *logfile; >+- static const char *logfn, *monhost; >++ static char *logfn, *monhost; >+ static sigset_t nut_upslog_sigmask; >+ static char logbuffer[LARGEBUF], *logformat; >+ >+ static flist_t *fhead = NULL; >++ struct monhost_child { >++ char *monhost; >++ char *logfn; >++ char *pidfilebase; >++ pid_t pid; >++ struct monhost_child *next; >++ }; >++ static struct monhost_child *monhost_child_anchor = NULL; >++ static struct monhost_child *monhost_child_current; >++ static struct monhost_child *monhost_child_prev = NULL; >++ static char *m_arg; >++ static struct sigaction upslog_sigaction; >++ static int trapped_signals[] = { SIGINT, SIGTERM, SIGCHLD }; >+ >++ >+ #define DEFAULT_LOGFORMAT "%TIME @Y@m@d @H@M@S% %VAR battery.charge% " \ >+ "%VAR input.voltage% %VAR ups.load% [%VAR ups.status%] " \ >+ "%VAR ups.temperature% %VAR input.frequency%" >+@@ -393,21 +412,33 @@ >+ * -u <username> >+ */ >+ >++static void term_handler(int signo) >++{ >++ if (signo != SIGCHLD && monhost_child_anchor != NULL) { >++ for (monhost_child_current = monhost_child_anchor; >++ monhost_child_current != NULL; >++ monhost_child_current = monhost_child_current->next) >++ kill(monhost_child_current->pid, signo); >++ exit(signo); >++ } >++} >++ >+ int main(int argc, char **argv) >+ { >+ int interval = 30, i, foreground = -1; >++ size_t monhost_len; >+ const char *prog = xbasename(argv[0]); >+ time_t now, nextpoll = 0; >+ const char *user = NULL; >+ struct passwd *new_uid = NULL; >+- const char *pidfilebase = prog; >++ char *pidfilebase = prog; >+ >+ logformat = DEFAULT_LOGFORMAT; >+ user = RUN_AS_USER; >+ >+ printf("Network UPS Tools %s %s\n", prog, UPS_VERSION); >+ >+- while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FB")) != -1) { >++ while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FBm:")) != -1) { >+ switch(i) { >+ case 'h': >+ help(prog); >+@@ -415,6 +446,19 @@ >+ break; >+ #endif >+ >++ case 'm': >++ monhost_child_prev = monhost_child_current; >++ monhost_child_current = malloc(sizeof(struct monhost_child)); >++ if (monhost_child_anchor == NULL) >++ monhost_child_anchor = monhost_child_current; >++ else >++ monhost_child_prev->next = monhost_child_current; >++ monhost_child_current->next = NULL; >++ m_arg = optarg; >++ monhost_child_current->monhost = strsep(&m_arg, ":"); >++ monhost_child_current->logfn = strsep(&m_arg, ":"); >++ monhost_child_current->pidfilebase = strsep(&m_arg, ":"); >++ break; >+ case 's': >+ monhost = optarg; >+ break; >+@@ -477,6 +521,29 @@ >+ >+ for (i = 3; i < argc; i++) >+ snprintfcat(logformat, LARGEBUF, "%s ", argv[i]); >++ } >++ >++ if (monhost_child_anchor != NULL) { >++ for (monhost_child_current = monhost_child_anchor; >++ monhost_child_current != NULL; >++ monhost_child_current = monhost_child_current->next) { >++ if ((monhost_child_current->pid = fork()) == 0) { >++ monhost = monhost_child_current->monhost; >++ logfn = monhost_child_current->logfn; >++ pidfilebase = monhost_child_current->pidfilebase; >++ break; >++ } >++ } >++ if (monhost_child_anchor->pid) { >++ for (i = 0; i++; i < sizeof(trapped_signals)/sizeof(int)) { >++ upslog_sigaction.sa_handler = &term_handler; >++ sigfillset(&upslog_sigaction.sa_mask); >++ upslog_sigaction.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT; >++ sigaction(trapped_signals[i], &upslog_sigaction, NULL); } >++ writepid(pidfilebase); >++ while(wait(wait_status)); >++ exit(EXIT_SUCCESS); >++ } >+ } >+ >+ if (!monhost) >diff --git a/sysutils/nut-devel/pkg-plist b/sysutils/nut-devel/pkg-plist >index 66f4d6398ca9..36e44704cbb3 100644 >--- a/sysutils/nut-devel/pkg-plist >+++ b/sysutils/nut-devel/pkg-plist >@@ -18,6 +18,7 @@ > @sample %%ETCDIR%%/upsmon.conf.sample > @sample %%ETCDIR%%/upssched.conf.sample > @sample %%EXAMPLESDIR%%/newsyslog.sample etc/newsyslog.conf.d/nut.conf >+@sample %%EXAMPLESDIR%%/nut_upslog.sample etc/syslog.d/nut > @sample %%EXAMPLESDIR%%/syslog.sample etc/syslog.d/nut > %%USB%%etc/devd/nut-usb.conf > bin/nut-scanner >diff --git a/sysutils/nut/Makefile b/sysutils/nut/Makefile >index 4409b60de0af..e388164c19b6 100644 >--- a/sysutils/nut/Makefile >+++ b/sysutils/nut/Makefile >@@ -1,6 +1,6 @@ > PORTNAME= nut > PORTVERSION= 2.8.0 >-PORTREVISION= 6 >+PORTREVISION= 7 > CATEGORIES= sysutils > MASTER_SITES= http://www.networkupstools.org/source/${PORTVERSION:R}/ > >diff --git a/sysutils/nut/files/nut_upslog.sample b/sysutils/nut/files/nut_upslog.sample >new file mode 100644 >index 000000000000..126a47a70d3a >--- /dev/null >+++ b/sysutils/nut/files/nut_upslog.sample >@@ -0,0 +1,52 @@ >+#!/bin/sh >+ >+# Authored by vvd@unislabs.com. >+ >+# PROVIDE: nut_upslog >+# REQUIRE: NETWORKING nut >+# BEFORE: LOGIN >+# KEYWORD: shutdown >+ >+. /etc/rc.subr >+ >+case $0 in >+/etc/rc*) >+ # during boot (shutdown) $0 is /etc/rc (/etc/rc.shutdown), >+ # so get the name of the script from $_file >+ name=$_file >+ ;; >+*) >+ name=$0 >+ ;; >+esac >+ >+name=${name##*/} >+rcvar=${name}_enable >+ >+load_rc_config "${name}" >+ >+# Define these nut_upslog* variables in one of these files: >+# /etc/rc.conf >+# /etc/rc.conf.local >+# /etc/rc.conf.d/nut_upslog >+# >+# If you want to log several different UPSes: >+# ln -s nut_upslog /usr/local/etc/rc.d/NAME >+# then set variables NAME_enable, NAME_ups, NAME_pidbase, NAME_logfile and etc. >+# >+# DO NOT CHANGE THESE DEFAULT VALUES HERE >+# >+eval "${rcvar}=\${${rcvar}:-'NO'}" >+eval "_prefix=\${${name}_prefix:-'/usr/local'}" >+eval "_logfile=\${${name}_logfile:-'/var/log/nut/ups.log'}" >+eval "_interval=\${${name}_interval:-'300'}" >+eval "_ups=\${${name}_ups:-'myups@localhost'}" >+eval "_pidbase=\${${name}_pidbase:-'upslog'}" >+eval "_format=\${${name}_format:+-f \${${name}_format}}" >+eval "${name}_flags=\${${name}_flags:-'-s ${_ups} -l ${_logfile} -i ${_interval} -p ${_pidbase} ${_format}'}" >+ >+required_dirs="%%STATEDIR%%" >+pidfile="%%STATEDIR%%/${_pidbase}.pid" >+command="${_prefix}/bin/upslog" >+ >+run_rc_command "$1" >diff --git a/sysutils/nut/files/patch-clients_upslog.c b/sysutils/nut/files/patch-clients_upslog.c >new file mode 100644 >index 000000000000..699abd785325 >--- /dev/null >+++ b/sysutils/nut/files/patch-clients_upslog.c >@@ -0,0 +1,133 @@ >+--- clients/upslog.c.orig 2022-08-21 09:28:11.630024000 -0700 >++++ clients/upslog.c 2022-08-21 10:23:05.691271000 -0700 >+@@ -32,6 +32,10 @@ >+ */ >+ >+ #include "common.h" >++#include <signal.h> >++#include <unistd.h> >++#include <sys/types.h> >++#include <sys/wait.h> >+ #include "nut_platform.h" >+ #include "upsclient.h" >+ >+@@ -41,17 +45,32 @@ >+ #include "upslog.h" >+ >+ static int reopen_flag = 0, exit_flag = 0; >++ static int wait_status, child_pid; >+ static uint16_t port; >+ static char *upsname, *hostname; >+ static UPSCONN_t ups; >+ >+ static FILE *logfile; >+- static const char *logfn, *monhost; >++ static char *logfn, *monhost; >+ static sigset_t nut_upslog_sigmask; >+ static char logbuffer[LARGEBUF], *logformat; >+ >+ static flist_t *fhead = NULL; >++ struct monhost_child { >++ char *monhost; >++ char *logfn; >++ char *pidfilebase; >++ pid_t pid; >++ struct monhost_child *next; >++ }; >++ static struct monhost_child *monhost_child_anchor = NULL; >++ static struct monhost_child *monhost_child_current; >++ static struct monhost_child *monhost_child_prev = NULL; >++ static char *m_arg; >++ static struct sigaction upslog_sigaction; >++ static int trapped_signals[] = { SIGINT, SIGTERM, SIGCHLD }; >+ >++ >+ #define DEFAULT_LOGFORMAT "%TIME @Y@m@d @H@M@S% %VAR battery.charge% " \ >+ "%VAR input.voltage% %VAR ups.load% [%VAR ups.status%] " \ >+ "%VAR ups.temperature% %VAR input.frequency%" >+@@ -393,21 +412,33 @@ >+ * -u <username> >+ */ >+ >++static void term_handler(int signo) >++{ >++ if (signo != SIGCHLD && monhost_child_anchor != NULL) { >++ for (monhost_child_current = monhost_child_anchor; >++ monhost_child_current != NULL; >++ monhost_child_current = monhost_child_current->next) >++ kill(monhost_child_current->pid, signo); >++ exit(signo); >++ } >++} >++ >+ int main(int argc, char **argv) >+ { >+ int interval = 30, i, foreground = -1; >++ size_t monhost_len; >+ const char *prog = xbasename(argv[0]); >+ time_t now, nextpoll = 0; >+ const char *user = NULL; >+ struct passwd *new_uid = NULL; >+- const char *pidfilebase = prog; >++ char *pidfilebase = prog; >+ >+ logformat = DEFAULT_LOGFORMAT; >+ user = RUN_AS_USER; >+ >+ printf("Network UPS Tools %s %s\n", prog, UPS_VERSION); >+ >+- while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FB")) != -1) { >++ while ((i = getopt(argc, argv, "+hs:l:i:f:u:Vp:FBm:")) != -1) { >+ switch(i) { >+ case 'h': >+ help(prog); >+@@ -415,6 +446,19 @@ >+ break; >+ #endif >+ >++ case 'm': >++ monhost_child_prev = monhost_child_current; >++ monhost_child_current = malloc(sizeof(struct monhost_child)); >++ if (monhost_child_anchor == NULL) >++ monhost_child_anchor = monhost_child_current; >++ else >++ monhost_child_prev->next = monhost_child_current; >++ monhost_child_current->next = NULL; >++ m_arg = optarg; >++ monhost_child_current->monhost = strsep(&m_arg, ":"); >++ monhost_child_current->logfn = strsep(&m_arg, ":"); >++ monhost_child_current->pidfilebase = strsep(&m_arg, ":"); >++ break; >+ case 's': >+ monhost = optarg; >+ break; >+@@ -477,6 +521,29 @@ >+ >+ for (i = 3; i < argc; i++) >+ snprintfcat(logformat, LARGEBUF, "%s ", argv[i]); >++ } >++ >++ if (monhost_child_anchor != NULL) { >++ for (monhost_child_current = monhost_child_anchor; >++ monhost_child_current != NULL; >++ monhost_child_current = monhost_child_current->next) { >++ if ((monhost_child_current->pid = fork()) == 0) { >++ monhost = monhost_child_current->monhost; >++ logfn = monhost_child_current->logfn; >++ pidfilebase = monhost_child_current->pidfilebase; >++ break; >++ } >++ } >++ if (monhost_child_anchor->pid) { >++ for (i = 0; i++; i < sizeof(trapped_signals)/sizeof(int)) { >++ upslog_sigaction.sa_handler = &term_handler; >++ sigfillset(&upslog_sigaction.sa_mask); >++ upslog_sigaction.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT; >++ sigaction(trapped_signals[i], &upslog_sigaction, NULL); } >++ writepid(pidfilebase); >++ while(wait(wait_status)); >++ exit(EXIT_SUCCESS); >++ } >+ } >+ >+ if (!monhost) >diff --git a/sysutils/nut/pkg-plist b/sysutils/nut/pkg-plist >index 51fabcb8782c..2c8525597e8f 100644 >--- a/sysutils/nut/pkg-plist >+++ b/sysutils/nut/pkg-plist >@@ -18,6 +18,7 @@ > @sample %%ETCDIR%%/upsmon.conf.sample > @sample %%ETCDIR%%/upssched.conf.sample > @sample %%EXAMPLESDIR%%/newsyslog.sample etc/newsyslog.conf.d/nut.conf >+@sample %%EXAMPLESDIR%%/nut_upslog.sample etc/syslog.d/nut > @sample %%EXAMPLESDIR%%/syslog.sample etc/syslog.d/nut > %%USB%%etc/devd/nut-usb.conf > bin/nut-scanner >-- >2.37.2 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 265963
:
236026
|
236030
|
236045
|
236049
|
236051
|
236052
|
236072
|
236073
|
236121
|
236127
|
236128
|
236132
|
236194
|
236219
|
236238
|
236243