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

Support LIBUSB_DEBUG=NUM setting in ups.conf #2649

Merged
merged 2 commits into from
Oct 2, 2024
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
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
Loading