Skip to content

Commit

Permalink
Merge pull request #2649 from jimklimov/issue-2616
Browse files Browse the repository at this point in the history
Support `LIBUSB_DEBUG=NUM` setting in `ups.conf`
  • Loading branch information
jimklimov authored Oct 2, 2024
2 parents 1560afe + e4d425e commit fd6f418
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 12 deletions.
5 changes: 5 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,11 @@ https://github.com/networkupstools/nut/milestone/11
of an UPS interface on a composite USB device or when looking at devices
with non-default interface/endpoint/config numbers. [PR #2611]
- USB drivers should now accept a `LIBUSB_DEBUG=INTEGER` setting in `ups.conf`
(as well as an environment variable that can be generally set via `nut.conf`
or service unit methods or init script), to enable troubleshooting of LibUSB
itself. [issue #2616]
- Introduced a new driver concept for interaction with OS-reported hardware
monitoring readings. Currently instantiated as `hwmon_ina219` specifically
made for Texas Instruments INA219 chip as exposed in the Linux "hwmon"
Expand Down
11 changes: 9 additions & 2 deletions conf/ups.conf.sample
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@
# Set maxretry to 3 by default, this should mitigate race with slow devices:
maxretry = 3

# These directives can be set outside and inside a driver definition, with
# slightly different meanings per context:
# These directives can be set outside and inside a driver definition,
# sometimes with slightly different meanings per context:
#
# maxstartdelay: OPTIONAL. This can be set as a global variable
# above your first UPS definition and it can also be
Expand Down Expand Up @@ -111,6 +111,13 @@ maxretry = 3
# `debug_min` are set, the driver-level setting takes precedence.
# Command-line option `-D` can only increase this verbosity level.
#
# LIBUSB_DEBUG: OPTIONAL. For run-time troubleshooting of USB-capable NUT
# drivers, you can specify the verbosity of LibUSB specific
# debugging as a numeric value such as `4` ("All messages
# are emitted"). Should not have any practical impact on
# other NUT drivers. For more details, see the library's
# documentation at e.g. https://libusb.sourceforge.io/api-1.0/
#
# user, group: OPTIONAL. Overrides the compiled-in (also global-section,
# when used in driver section) default unprivileged user/group
# name for NUT device driver. Impacts access rights used for
Expand Down
19 changes: 11 additions & 8 deletions docs/man/nut_usb_addvars.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,21 @@ As a rule of thumb for `usb_hid_desc_index` discovery, you can see larger
`wDescriptorLength` values (roughly 600+ bytes) in reports of `lsusb` or
similar tools.

[NOTE]
======
*LIBUSB_DEBUG =* 'INTEGER'::

Run-time troubleshooting of USB-capable NUT drivers can involve not only
raising the common NUT debug verbosity (e.g. using the `DEBUG_MIN` setting
in linkman:ups.conf[5] or protocol commands to change the `driver.debug`
value), but may also benefit from LibUSB specific debugging.

For the latter, currently you would have to export the environment variable
`LIBUSB_DEBUG` before starting a NUT driver (may be set and "exported" via
linkman:nut.conf[5]), to a numeric value such as `4` ("All messages are
emitted"). For more details, including the currently supported values, see:
+
For the latter, you can set the `LIBUSB_DEBUG` driver option; alternatively
you can classically export the environment variable `LIBUSB_DEBUG` before
starting a NUT driver program (may be set and "exported" in driver init
script or service method, perhaps via linkman:nut.conf[5]), to a numeric
value such as `4` ("All messages are emitted").
+
For more details, including the currently supported values for your version
of the library, see e.g.:

* https://libusb.sourceforge.io/api-1.0/
* https://libusb.sourceforge.io/api-1.0/group__libusb__lib.html
======
25 changes: 25 additions & 0 deletions docs/man/ups.conf.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,19 @@ troubleshooting a deployment, without impacting foreground or background
running mode directly. Command-line option `-D` can only increase this
verbosity level.

*LIBUSB_DEBUG* 'INTEGER'::

Optional. For run-time troubleshooting of USB-capable NUT drivers,
you can specify verbosity of LibUSB specific debugging as a numeric
value such as `4` ("All messages are emitted"). Should not have any
practical impact on other NUT drivers.
+
For more details, including the currently supported values for your
version of the library, see e.g.:

* https://libusb.sourceforge.io/api-1.0/
* https://libusb.sourceforge.io/api-1.0/group__libusb__lib.html

UPS FIELDS
----------

Expand Down Expand Up @@ -325,6 +338,18 @@ running mode directly. If the global `debug_min` is also set, this
driver-level setting overrides it. Command-line option `-D` can only
increase this verbosity level.

*LIBUSB_DEBUG* 'INTEGER'::

Optional. For run-time troubleshooting of USB-capable NUT drivers,
you can specify verbosity of LibUSB specific debugging as a numeric
value such as `4` ("All messages are emitted").
+
For more details, including the currently supported values for your
version of the library, see e.g.:

* https://libusb.sourceforge.io/api-1.0/
* https://libusb.sourceforge.io/api-1.0/group__libusb__lib.html

INTEGRATION
-----------

Expand Down
48 changes: 46 additions & 2 deletions drivers/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,7 @@ static int main_arg(char *var, char *val)
* Note: during reload_flag!=0 handling this is reset to -1, to
* catch commented-away settings, so not checking previous value.
*/
if (!strcmp(var, "debug_min")) {
if (!strcasecmp(var, "debug_min")) {
int lvl = -1; /* typeof common/common.c: int nut_debug_level */
if ( str_to_int (val, &lvl, 10) && lvl >= 0 ) {
nut_debug_level_driver = lvl;
Expand All @@ -1074,6 +1074,28 @@ static int main_arg(char *var, char *val)
return 1; /* handled */
}

if (!strcmp(var, "LIBUSB_DEBUG")) {
int lvl = -1; /* https://libusb.sourceforge.io/api-1.0/group__libusb__lib.html#ga2d6144203f0fc6d373677f6e2e89d2d2 */
int msglvl = 1;
char buf[SMALLBUF], *s = getenv("LIBUSB_DEBUG");

if (!str_to_int(val, &lvl, 10) || lvl < 0) {
lvl = 4;
upslogx(LOG_INFO, "WARNING : Invalid LIBUSB_DEBUG value found in ups.conf for the driver, defaulting to %d", lvl);
}
if (nut_debug_level < 1 && nut_debug_level_driver < 1 && nut_debug_level_global < 1)
msglvl = 0;

if (s)
upsdebugx(msglvl, "Old value of LIBUSB_DEBUG=%s in envvars", s);

snprintf(buf, sizeof(buf), "%d", lvl);
upsdebugx(msglvl, "Enabling LIBUSB_DEBUG=%s from ups.conf", buf);
setenv("LIBUSB_DEBUG", buf, 1);

return 1; /* handled */
}

return 0; /* unhandled, pass it through to the driver */
}

Expand Down Expand Up @@ -1189,7 +1211,7 @@ static void do_global_args(const char *var, const char *val)
* Note: during reload_flag!=0 handling this is reset to -1, to
* catch commented-away settings, so not checking previous value.
*/
if (!strcmp(var, "debug_min")) {
if (!strcasecmp(var, "debug_min")) {
int lvl = -1; /* typeof common/common.c: int nut_debug_level */
if ( str_to_int (val, &lvl, 10) && lvl >= 0 ) {
nut_debug_level_global = lvl;
Expand All @@ -1200,6 +1222,28 @@ static void do_global_args(const char *var, const char *val)
return;
}

if (!strcmp(var, "LIBUSB_DEBUG")) {
int lvl = -1; /* https://libusb.sourceforge.io/api-1.0/group__libusb__lib.html#ga2d6144203f0fc6d373677f6e2e89d2d2 */
int msglvl = 1;
char *s = getenv("LIBUSB_DEBUG");

if (!str_to_int(val, &lvl, 10) || lvl < 0) {
lvl = 4;
upslogx(LOG_INFO, "WARNING : Invalid LIBUSB_DEBUG value found in ups.conf for the driver, defaulting to %d", lvl);
}
if (nut_debug_level < 1 && nut_debug_level_driver < 1 && nut_debug_level_global < 1)
msglvl = 0;

if (s)
upsdebugx(msglvl, "Old value of LIBUSB_DEBUG=%s in envvars", s);

snprintf(buf, sizeof(buf), "%d", lvl);
upsdebugx(msglvl, "Enabling LIBUSB_DEBUG=%s from ups.conf", buf);
setenv("LIBUSB_DEBUG", buf, 1);

return;
}

/* unrecognized */
}

Expand Down
4 changes: 4 additions & 0 deletions include/nutconf.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1667,6 +1667,7 @@ class UpsConfiguration : public GenericConfiguration
inline bool getNoWait() const { return getFlag("nowait"); }

inline long long int getDebugMin() const { return getInt("debug_min"); }
inline long long int getLibusbDebug() const { return getInt("LIBUSB_DEBUG"); }
inline long long int getMaxRetry() const { return getInt("maxretry"); }
inline long long int getMaxStartDelay() const { return getInt("maxstartdelay"); }
inline long long int getPollInterval() const { return getInt("pollinterval", 5); } // TODO: check the default
Expand All @@ -1681,6 +1682,7 @@ class UpsConfiguration : public GenericConfiguration
inline void setNoWait(bool val = true) { setFlag("nowait", val); }

inline void setDebugMin(long long int num) { setInt("debug_min", num); }
inline void setLibusbDebug(long long int num) { setInt("LIBUSB_DEBUG", num); }
inline void setMaxRetry(long long int num) { setInt("maxretry", num); }
inline void setMaxStartDelay(long long int delay) { setInt("maxstartdelay", delay); }
inline void setPollInterval(long long int interval) { setInt("pollinterval", interval); }
Expand Down Expand Up @@ -1848,6 +1850,7 @@ class UpsConfiguration : public GenericConfiguration
inline long long int getDaysOff(const std::string & ups) const { return getInt(ups, "daysoff"); } // CHECKME
inline long long int getDaySweek(const std::string & ups) const { return getInt(ups, "daysweek"); } // CHECKME
inline long long int getDebugMin(const std::string & ups) const { return getInt(ups, "debug_min"); }
inline long long int getLibusbDebug(const std::string & ups) const { return getInt(ups, "LIBUSB_DEBUG"); }
inline long long int getFrequency(const std::string & ups) const { return getInt(ups, "frequency"); } // CHECKME
inline long long int getHourOff(const std::string & ups) const { return getInt(ups, "houroff"); } // CHECKME
inline long long int getHourOn(const std::string & ups) const { return getInt(ups, "houron"); } // CHECKME
Expand Down Expand Up @@ -2061,6 +2064,7 @@ class UpsConfiguration : public GenericConfiguration
inline void setDaysOff(const std::string & ups, long long int daysoff) { setInt(ups, "daysoff", daysoff); } // CHECKME
inline void setDaysWeek(const std::string & ups, long long int daysweek) { setInt(ups, "daysweek", daysweek); } // CHECKME
inline void setDebugMin(const std::string & ups, long long int val) { setInt(ups, "debug_min", val); }
inline void setLibusbDebug(const std::string & ups, long long int val) { setInt(ups, "LIBUSB_DEBUG", val); }
inline void setFrequency(const std::string & ups, long long int frequency) { setInt(ups, "frequency", frequency); } // CHECKME
inline void setHourOff(const std::string & ups, long long int houroff) { setInt(ups, "houroff", houroff); } // CHECKME
inline void setHourOn(const std::string & ups, long long int houron) { setInt(ups, "houron", houron); } // CHECKME
Expand Down

0 comments on commit fd6f418

Please sign in to comment.