Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce driver.state tracking #1771

Merged
merged 5 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,9 @@ https://github.com/networkupstools/nut/milestone/8
- Stuck drivers that do not react to `SIGTERM` quickly are now retried with
`SIGKILL` [#1424]

- Each driver should now report its `driver.state` to help readers determine
whether it is initializing, reconnecting, or running regular loops [#1767]

- Code which resolves full paths to libraries should now consider the common
environment variable `LD_LIBRARY_PATH` as a preferred possible override
to built-in paths (note that most operating systems advise against setting
Expand Down
12 changes: 12 additions & 0 deletions docs/nut-names.txt
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,18 @@ driver: Internal driver information
cmdline -x) setting | (varies)
| driver.flag.xxx | Flag xxx (ups.conf or
cmdline -x) status | enabled (or absent)
| driver.state | Current state in driver's
lifecycle, primarily to help
readers discern long-running
init (with full device walk)
or cleanup stages from
the stable working loop | init.starting, init.quiet,
init.device, init.info,
init.updateinfo (first walk),
reconnect.trying,
reconnect.updateinfo,
updateinfo, quiet, dumping,
cleanup.upsdrv, cleanup.exit
|===============================================================================

server: Internal server information
Expand Down
3 changes: 2 additions & 1 deletion docs/nut.dict
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 3069 utf-8
personal_ws-1.1 en 3075 utf-8
AAS
ABI
ACFAIL
Expand Down Expand Up @@ -2150,6 +2150,7 @@ licensor
licensors
liebert
liebertgxt
lifecycle
linesensitivity
linevoltage
linkdoc
Expand Down
3 changes: 3 additions & 0 deletions drivers/adelsystem_cbi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,7 @@ void modbus_reconnect(void)
int rval;

upsdebugx(1, "modbus_reconnect, trying to reconnect to modbus server");
dstate_setinfo("driver.state", "reconnect.trying");

/* clear current modbus context */
modbus_close(mbctx);
Expand Down Expand Up @@ -1340,5 +1341,7 @@ void modbus_reconnect(void)
}
/* #elif (defined NUT_MODBUS_TIMEOUT_ARG_timeval) // some un-castable type in fields */
#endif /* NUT_MODBUS_TIMEOUT_ARG_* */

dstate_setinfo("driver.state", "quiet");
}

5 changes: 5 additions & 0 deletions drivers/bcmxcp_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,13 +385,18 @@ void upsdrv_cleanup(void)

void upsdrv_reconnect(void)
{
dstate_setinfo("driver.state", "reconnect.trying");

upsdebugx(4, "==================================================");
upsdebugx(4, "= device has been disconnected, try to reconnect =");
upsdebugx(4, "==================================================");

nutusb_close(upsdev, "USB");
upsdev = NULL;

upsdrv_initups();

dstate_setinfo("driver.state", "quiet");
}

/* USB functions */
Expand Down
5 changes: 5 additions & 0 deletions drivers/blazer_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,11 +445,15 @@ ssize_t blazer_command(const char *cmd, char *buf, size_t buflen)
ssize_t ret;

if (udev == NULL) {
dstate_setinfo("driver.state", "reconnect.trying");

ret = usb->open_dev(&udev, &usbdevice, reopen_matcher, NULL);

if (ret < 1) {
return ret;
}

dstate_setinfo("driver.state", "reconnect.updateinfo");
}

ret = (*subdriver_command)(cmd, buf, buflen);
Expand Down Expand Up @@ -496,6 +500,7 @@ ssize_t blazer_command(const char *cmd, char *buf, size_t buflen)
case LIBUSB_ERROR_NOT_FOUND: /* No such file or directory */
fallthrough_case_reconnect:
/* Uh oh, got to reconnect! */
dstate_setinfo("driver.state", "reconnect.trying");
usb->close_dev(udev);
udev = NULL;
break;
Expand Down
3 changes: 3 additions & 0 deletions drivers/generic_modbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -1038,6 +1038,7 @@ void modbus_reconnect(void)
int rval;

upsdebugx(2, "modbus_reconnect, trying to reconnect to modbus server");
dstate_setinfo("driver.state", "reconnect.trying");

/* clear current modbus context */
modbus_close(mbctx);
Expand Down Expand Up @@ -1097,4 +1098,6 @@ void modbus_reconnect(void)
}
/* #elif (defined NUT_MODBUS_TIMEOUT_ARG_timeval) // some un-castable type in fields */
#endif /* NUT_MODBUS_TIMEOUT_ARG_* */

dstate_setinfo("driver.state", "quiet");
}
29 changes: 26 additions & 3 deletions drivers/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,8 +631,16 @@ static void vartab_free(void)
}
}

static void exit_upsdrv_cleanup(void)
{
dstate_setinfo("driver.state", "cleanup.upsdrv");
upsdrv_cleanup();
}

static void exit_cleanup(void)
{
dstate_setinfo("driver.state", "cleanup.exit");

if (!dump_data) {
upsnotify(NOTIFY_STATE_STOPPING, "exit_cleanup()");
}
Expand Down Expand Up @@ -695,6 +703,8 @@ int main(int argc, char **argv)
int i, do_forceshutdown = 0;
int update_count = 0;

dstate_setinfo("driver.state", "init.starting");

atexit(exit_cleanup);

/* pick up a default from configure --with-user */
Expand Down Expand Up @@ -1000,10 +1010,12 @@ int main(int argc, char **argv)
* when its a pdu! */
dstate_setinfo("device.type", "ups");

dstate_setinfo("driver.state", "init.device");
upsdrv_initups();
dstate_setinfo("driver.state", "init.quiet");

/* UPS is detected now, cleanup upon exit */
atexit(upsdrv_cleanup);
atexit(exit_upsdrv_cleanup);

/* now see if things are very wrong out there */
if (upsdrv_info.status == DRV_BROKEN) {
Expand All @@ -1027,8 +1039,13 @@ int main(int argc, char **argv)
syslogbit_set();

/* get the base data established before allowing connections */
dstate_setinfo("driver.state", "init.info");
upsdrv_initinfo();
/* Note: a few drivers also call their upsdrv_updateinfo() during
* their upsdrv_initinfo(), possibly to impact the initialization */
dstate_setinfo("driver.state", "init.updateinfo");
upsdrv_updateinfo();
dstate_setinfo("driver.state", "init.quiet");

if (dstate_getinfo("driver.flag.ignorelb")) {
int have_lb_method = 0;
Expand Down Expand Up @@ -1151,12 +1168,15 @@ int main(int argc, char **argv)
writepid(pidfn); /* PID changes when backgrounding */
}

if (!dump_data) {
dstate_setinfo("driver.state", "quiet");
if (dump_data) {
upsdebugx(1, "Driver initialization completed, beginning data dump (%d loops)", dump_data);
} else {
upsdebugx(1, "Driver initialization completed, beginning regular infinite loop");
upsnotify(NOTIFY_STATE_READY_WITH_PID, NULL);
}

while (!exit_flag) {

struct timeval timeout;

if (!dump_data) {
Expand All @@ -1166,12 +1186,15 @@ int main(int argc, char **argv)
gettimeofday(&timeout, NULL);
timeout.tv_sec += poll_interval;

dstate_setinfo("driver.state", "updateinfo");
upsdrv_updateinfo();
dstate_setinfo("driver.state", "quiet");

/* Dump the data tree (in upsc-like format) to stdout and exit */
if (dump_data) {
/* Wait for 'dump_data' update loops to ensure data completion */
if (update_count == dump_data) {
dstate_setinfo("driver.state", "dumping");
dstate_dump();
exit_flag = 1;
}
Expand Down
5 changes: 5 additions & 0 deletions drivers/nutdrv_qx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3163,11 +3163,15 @@ static ssize_t qx_command(const char *cmd, char *buf, size_t buflen)
# endif /* QX_SERIAL (&& QX_USB)*/

if (udev == NULL) {
dstate_setinfo("driver.state", "reconnect.trying");

ret = usb->open_dev(&udev, &usbdevice, reopen_matcher, NULL);

if (ret < 1) {
return ret;
}

dstate_setinfo("driver.state", "reconnect.updateinfo");
}

ret = (*subdriver_command)(cmd, buf, buflen);
Expand Down Expand Up @@ -3229,6 +3233,7 @@ static ssize_t qx_command(const char *cmd, char *buf, size_t buflen)
case LIBUSB_ERROR_NOT_FOUND: /* No such file or directory */
fallthrough_case_reconnect:
/* Uh oh, got to reconnect! */
dstate_setinfo("driver.state", "reconnect.trying");
usb->close_dev(udev);
udev = NULL;
break;
Expand Down
3 changes: 3 additions & 0 deletions drivers/powerman-pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,8 @@ static int reconnect_ups(void)
{
pm_err_t rv;

dstate_setinfo("driver.state", "reconnect.trying");

upsdebugx(4, "===================================================");
upsdebugx(4, "= connection lost with Powerman, try to reconnect =");
upsdebugx(4, "===================================================");
Expand All @@ -202,6 +204,7 @@ static int reconnect_ups(void)
if ((rv = pm_connect(device_path, NULL, &pm, 0)) != PM_ESUCCESS)
return 0;
else {
dstate_setinfo("driver.state", "quiet");
upsdebugx(4, "connection restored with Powerman");
return 1;
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/richcomm_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,11 +638,13 @@ void upsdrv_updateinfo(void)
int ret, online, battery_normal;

if (!udev) {
dstate_setinfo("driver.state", "reconnect.trying");
ret = usb_device_open(&udev, &usbdevice, &device_matcher, &driver_callback);

if (ret < 0) {
return;
}
dstate_setinfo("driver.state", "reconnect.updateinfo");
}

ret = query_ups(reply);
Expand All @@ -651,6 +653,7 @@ void upsdrv_updateinfo(void)
usb_comm_fail("Query to UPS failed");
dstate_datastale();

dstate_setinfo("driver.state", "reconnect.trying");
usb_device_close(udev);
udev = NULL;

Expand Down
5 changes: 5 additions & 0 deletions drivers/riello_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,13 +348,17 @@ static int riello_command(uint8_t *cmd, uint8_t *buf, uint16_t length, uint16_t
int ret;

if (udev == NULL) {
dstate_setinfo("driver.state", "reconnect.trying");

ret = usb->open_dev(&udev, &usbdevice, reopen_matcher, &driver_callback);

upsdebugx (3, "riello_command err udev NULL : %d ", ret);
if (ret < 0)
return ret;

dstate_setinfo("driver.state", "reconnect.updateinfo");
upsdrv_initinfo(); /* reconnect usb cable */
dstate_setinfo("driver.state", "quiet");
}

ret = (*subdriver_command)(cmd, buf, length, buflen);
Expand Down Expand Up @@ -404,6 +408,7 @@ static int riello_command(uint8_t *cmd, uint8_t *buf, uint16_t length, uint16_t
case LIBUSB_ERROR_NOT_FOUND: /* No such file or directory */
fallthrough_case_reconnect:
/* Uh oh, got to reconnect! */
dstate_setinfo("driver.state", "reconnect.trying");
usb->close_dev(udev);
udev = NULL;
break;
Expand Down
6 changes: 6 additions & 0 deletions drivers/tripplite_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,8 @@ static int reconnect_ups(void)
return 1;
}

dstate_setinfo("driver.state", "reconnect.trying");

upsdebugx(2, "==================================================");
upsdebugx(2, "= device has been disconnected, try to reconnect =");
upsdebugx(2, "==================================================");
Expand All @@ -337,6 +339,7 @@ static int reconnect_ups(void)
}

hd = &curDevice;
dstate_setinfo("driver.state", "quiet");

return ret;
}
Expand Down Expand Up @@ -552,6 +555,7 @@ static void usb_comm_fail(int res, const char *msg)
#endif

default:
dstate_setinfo("driver.state", "reconnect.trying");
upslogx(LOG_WARNING,
"%s: Device detached? (error %d: %s)",
msg, res, nut_usb_strerror(res));
Expand All @@ -563,7 +567,9 @@ static void usb_comm_fail(int res, const char *msg)
if(hd) {
upslogx(LOG_NOTICE, "Successfully reconnected");
try = 0;
dstate_setinfo("driver.state", "reconnect.updateinfo");
upsdrv_initinfo();
dstate_setinfo("driver.state", "quiet");
} else {
if(try > MAX_RECONNECT_TRIES) {
fatalx(EXIT_FAILURE, "Too many unsuccessful reconnection attempts");
Expand Down
7 changes: 7 additions & 0 deletions drivers/usbhid-ups.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,10 +888,12 @@ void upsdrv_updateinfo(void)
case LIBUSB_ERROR_NO_MEM: /* Insufficient memory */
fallthrough_reconnect:
/* Uh oh, got to reconnect! */
dstate_setinfo("driver.state", "reconnect.trying");
hd = NULL;
return;
case LIBUSB_ERROR_IO: /* I/O error */
/* Uh oh, got to reconnect, with a special suggestion! */
dstate_setinfo("driver.state", "reconnect.trying");
interrupt_pipe_EIO_count++;
hd = NULL;
return;
Expand Down Expand Up @@ -1510,11 +1512,13 @@ static bool_t hid_ups_walk(walkmode_t mode)
case LIBUSB_ERROR_NO_MEM: /* Insufficient memory */
fallthrough_reconnect:
/* Uh oh, got to reconnect! */
dstate_setinfo("driver.state", "reconnect.trying");
hd = NULL;
return FALSE;

case LIBUSB_ERROR_IO: /* I/O error */
/* Uh oh, got to reconnect, with a special suggestion! */
dstate_setinfo("driver.state", "reconnect.trying");
interrupt_pipe_EIO_count++;
hd = NULL;
return FALSE;
Expand Down Expand Up @@ -1595,6 +1599,8 @@ static int reconnect_ups(void)
char *val;
int wait_before_reconnect = 0;

dstate_setinfo("driver.state", "reconnect.trying");

/* Init time to wait before trying to reconnect (seconds) */
val = getval(HU_VAR_WAITBEFORERECONNECT);
if (val) {
Expand Down Expand Up @@ -1627,6 +1633,7 @@ static int reconnect_ups(void)
return 1;
}

dstate_setinfo("driver.state", "quiet");
return 0;
}

Expand Down