···524524 <link linkend="opt-services.ananicy.enable">services.ananicy</link>.
525525 </para>
526526 </listitem>
527527+ <listitem>
528528+ <para>
529529+ <link xlink:href="https://github.com/prometheus-community/smartctl_exporter">smartctl_exporter</link>,
530530+ a Prometheus exporter for
531531+ <link xlink:href="https://en.wikipedia.org/wiki/S.M.A.R.T.">S.M.A.R.T.</link>
532532+ data. Available as
533533+ <link xlink:href="options.html#opt-services.prometheus.exporters.smartctl.enable">services.prometheus.exporters.smartctl</link>.
534534+ </para>
535535+ </listitem>
527536 </itemizedlist>
528537 </section>
529538 <section xml:id="sec-release-21.11-incompatibilities">
+2
nixos/doc/manual/release-notes/rl-2111.section.md
···147147148148- Auto nice daemons [ananicy](https://github.com/Nefelim4ag/Ananicy) and [ananicy-cpp](https://gitlab.com/ananicy-cpp/ananicy-cpp/). Available as [services.ananicy](#opt-services.ananicy.enable).
149149150150+- [smartctl_exporter](https://github.com/prometheus-community/smartctl_exporter), a Prometheus exporter for [S.M.A.R.T.](https://en.wikipedia.org/wiki/S.M.A.R.T.) data. Available as [services.prometheus.exporters.smartctl](options.html#opt-services.prometheus.exporters.smartctl.enable).
151151+150152## Backward Incompatibilities {#sec-release-21.11-incompatibilities}
151153152154- The NixOS VM test framework, `pkgs.nixosTest`/`make-test-python.nix`, now requires detaching commands such as `succeed("foo &")` and `succeed("foo | xclip -i")` to close stdout.
···11+From e81b06df67b1d42ef915615fafa0b56ef956673b Mon Sep 17 00:00:00 2001
22+From: Andreas Fuchs <asf@boinkor.net>
33+Date: Thu, 11 Feb 2021 17:30:44 -0500
44+Subject: [PATCH] Return the cached value if it's not time to scan again yet
55+66+This should ensure that if we have a valid value cached (which ought
77+to be every time after the first scan), we return it as metrics.
88+99+This fixes the crashes that would happen if queries happened earlier
1010+than the re-scan interval allowed.
1111+1212+Address review feedback: Shorten the time-to-scan logic
1313+1414+We can express this in a single if statement, so it takes fewer lines
1515+to do the "should we check again" check.
1616+---
1717+ readjson.go | 11 ++---------
1818+ 1 file changed, 2 insertions(+), 9 deletions(-)
1919+2020+diff --git a/readjson.go b/readjson.go
2121+index da35448..c9996fd 100644
2222+--- a/readjson.go
2323++++ b/readjson.go
2424+@@ -78,14 +78,7 @@ func readData(device string) (gjson.Result, error) {
2525+2626+ if _, err := os.Stat(device); err == nil {
2727+ cacheValue, cacheOk := jsonCache[device]
2828+- timeToScan := false
2929+- if cacheOk {
3030+- timeToScan = time.Now().After(cacheValue.LastCollect.Add(options.SMARTctl.CollectPeriodDuration))
3131+- } else {
3232+- timeToScan = true
3333+- }
3434+-
3535+- if timeToScan {
3636++ if !cacheOk || time.Now().After(cacheValue.LastCollect.Add(options.SMARTctl.CollectPeriodDuration)) {
3737+ json, ok := readSMARTctl(device)
3838+ if ok {
3939+ jsonCache[device] = JSONCache{JSON: json, LastCollect: time.Now()}
4040+@@ -93,7 +86,7 @@ func readData(device string) (gjson.Result, error) {
4141+ }
4242+ return gjson.Parse(DEFAULT_EMPTY_JSON), fmt.Errorf("smartctl returned bad data for device %s", device)
4343+ }
4444+- return gjson.Parse(DEFAULT_EMPTY_JSON), fmt.Errorf("Too early collect called for device %s", device)
4545++ return cacheValue.JSON, nil
4646+ }
4747+ return gjson.Parse(DEFAULT_EMPTY_JSON), fmt.Errorf("Device %s unavialable", device)
4848+ }
4949+--
5050+2.33.1
5151+