diff --git a/src/report/report-basic.c b/src/report/report-basic.c index eb2fe6a498..5bcba6ceab 100644 --- a/src/report/report-basic.c +++ b/src/report/report-basic.c @@ -581,6 +581,11 @@ static int smbios_generate(const MetricFamily *mf, sd_varlink *link, void *userd assert(mf && mf->name); assert(link); + /* SMBIOS information might be accessible from a container, but it's information about the host, not + * the container, hence suppress it here */ + if (detect_container() > 0) + return 0; + /* Reports the fundamental SMBIOS/DMI identification fields. Some of these (serial numbers, asset * tags, the system UUID) are privacy sensitive and only readable by root — if we lack the * privileges to read them we simply skip them. */ @@ -644,6 +649,10 @@ static int tpm2_generate(const MetricFamily *mf, sd_varlink *link, void *userdat assert(mf && mf->name); assert(link); + /* TPMs are not virtualized for containers, let's suppress them here */ + if (detect_container() > 0) + return 0; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; r = sd_device_new_from_subsystem_sysname(&dev, "tpmrm", "tpmrm0"); if (r < 0) { diff --git a/src/report/report-hwmon.c b/src/report/report-hwmon.c index c557d67259..cbc849705d 100644 --- a/src/report/report-hwmon.c +++ b/src/report/report-hwmon.c @@ -14,6 +14,7 @@ #include "report-hwmon.h" #include "sort-util.h" #include "string-util.h" +#include "virt.h" /* The kernel's hwmon sysfs interface (see https://docs.kernel.org/hwmon/sysfs-interface.html) exposes * temperature sensors as temp_input attributes, in millidegrees Celsius. Only the current reading is @@ -181,6 +182,11 @@ static int hwmon_temperature_generate(const MetricFamily *mf, sd_varlink *link, assert(mf && mf->name); assert(link); + /* Temperature sensors are a hardware concept the host manages, not something specific to the systems + * down the container tree, hence let's not generate the metrics here, even if accessible. */ + if (detect_container() > 0) + return 0; + /* Note that a fresh enumerator (and hence fresh sd_device objects) is used for each call, so that * the sysattr cache in sd-device never hands out stale readings. */ _cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL; diff --git a/test/units/TEST-74-AUX-UTILS.report.sh b/test/units/TEST-74-AUX-UTILS.report.sh index 6d2f19c452..f2adf02544 100755 --- a/test/units/TEST-74-AUX-UTILS.report.sh +++ b/test/units/TEST-74-AUX-UTILS.report.sh @@ -66,35 +66,45 @@ echo "$net_metrics" | grep '"name":"io.systemd.Network.Address"' | grep '"object ip address del 192.0.2.1/32 dev lo # test io.systemd.HWMon Metrics -systemctl start systemd-report-hwmon.socket -varlinkctl info /run/systemd/report/io.systemd.HWMon -varlinkctl list-methods /run/systemd/report/io.systemd.HWMon -hwmon_describe="$(varlinkctl call --more /run/systemd/report/io.systemd.HWMon io.systemd.Metrics.Describe {})" -echo "$hwmon_describe" | jq --seq -r 'select(.name == "io.systemd.HWMon.TemperatureCelsius") | .type' | grep -wx gauge >/dev/null -# An empty result set is signalled through the io.systemd.Metrics.NoSuchMetric sentinel error, which is what -# VMs without any hwmon devices produce, hence treat it as success. -hwmon_metrics="$(varlinkctl call --more --graceful=io.systemd.Metrics.NoSuchMetric /run/systemd/report/io.systemd.HWMon io.systemd.Metrics.List {})" -# At most one row per readable, non-faulted temp_input attribute in sysfs. A sensor may become -# transiently unreadable between the two samples, hence only check the bound. VMs typically expose no hwmon -# devices at all, in which case both counts are zero. -hwmon_expected=0 -for f in /sys/class/hwmon/hwmon*/temp*_input; do - hwmon_fault="${f%_input}_fault" - if [[ -f "$hwmon_fault" ]] && [[ "$(cat "$hwmon_fault")" == 1 ]]; then - continue +hwmon_tests() { + # The hwmon socket is conditioned out in containers, since temperature sensors belong to the host + if systemd-detect-virt --quiet --container; then + echo "Skipping io.systemd.HWMon tests in container." + return 0 fi - if cat "$f" >/dev/null 2>&1; then - hwmon_expected=$((hwmon_expected + 1)) + + systemctl start systemd-report-hwmon.socket + varlinkctl info /run/systemd/report/io.systemd.HWMon + varlinkctl list-methods /run/systemd/report/io.systemd.HWMon + hwmon_describe="$(varlinkctl call --more /run/systemd/report/io.systemd.HWMon io.systemd.Metrics.Describe {})" + echo "$hwmon_describe" | jq --seq -r 'select(.name == "io.systemd.HWMon.TemperatureCelsius") | .type' | grep -wx gauge >/dev/null + # An empty result set is signalled through the io.systemd.Metrics.NoSuchMetric sentinel error, which is what + # VMs without any hwmon devices produce, hence treat it as success. + hwmon_metrics="$(varlinkctl call --more --graceful=io.systemd.Metrics.NoSuchMetric /run/systemd/report/io.systemd.HWMon io.systemd.Metrics.List {})" + # At most one row per readable, non-faulted temp_input attribute in sysfs. A sensor may become + # transiently unreadable between the two samples, hence only check the bound. VMs typically expose no hwmon + # devices at all, in which case both counts are zero. + hwmon_expected=0 + for f in /sys/class/hwmon/hwmon*/temp*_input; do + hwmon_fault="${f%_input}_fault" + if [[ -f "$hwmon_fault" ]] && [[ "$(cat "$hwmon_fault")" == 1 ]]; then + continue + fi + if cat "$f" >/dev/null 2>&1; then + hwmon_expected=$((hwmon_expected + 1)) + fi + done + hwmon_reported="$(echo "$hwmon_metrics" | jq --seq -r 'select(.name == "io.systemd.HWMon.TemperatureCelsius") | .fields.sensor' | wc -l)" + [[ "$hwmon_reported" -le "$hwmon_expected" ]] + if [[ "$hwmon_reported" -gt 0 ]]; then + # Every row must carry a numeric value, an object and a sensor field of the form temp + [[ "$(echo "$hwmon_metrics" | jq --seq -r 'select(.name == "io.systemd.HWMon.TemperatureCelsius") | ((.value | type) == "number") and ((.object | type) == "string") and (.fields.sensor | test("^temp[0-9]+$")) | tostring' | sort -u)" == "true" ]] fi -done -hwmon_reported="$(echo "$hwmon_metrics" | jq --seq -r 'select(.name == "io.systemd.HWMon.TemperatureCelsius") | .fields.sensor' | wc -l)" -[[ "$hwmon_reported" -le "$hwmon_expected" ]] -if [[ "$hwmon_reported" -gt 0 ]]; then - # Every row must carry a numeric value, an object and a sensor field of the form temp - [[ "$(echo "$hwmon_metrics" | jq --seq -r 'select(.name == "io.systemd.HWMon.TemperatureCelsius") | ((.value | type) == "number") and ((.object | type) == "string") and (.fields.sensor | test("^temp[0-9]+$")) | tostring' | sort -u)" == "true" ]] -fi -"$REPORT" describe io.systemd.HWMon -"$REPORT" metrics io.systemd.HWMon + "$REPORT" describe io.systemd.HWMon + "$REPORT" metrics io.systemd.HWMon +} + +hwmon_tests # test io.systemd.DiskSpace Metrics diff --git a/units/systemd-report-hwmon.socket b/units/systemd-report-hwmon.socket index 910e651908..51fc6e3619 100644 --- a/units/systemd-report-hwmon.socket +++ b/units/systemd-report-hwmon.socket @@ -13,6 +13,7 @@ Documentation=man:systemd-report-hwmon@.service(8) DefaultDependencies=no Before=sockets.target shutdown.target Conflicts=shutdown.target +ConditionVirtualization=!container [Socket] ListenStream=/run/systemd/report/io.systemd.HWMon