watchdog.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Copyright 2016 CoreOS, Inc.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package daemon
  15. import (
  16. "fmt"
  17. "os"
  18. "strconv"
  19. "time"
  20. )
  21. // SdWatchdogEnabled returns watchdog information for a service.
  22. // Processes should call daemon.SdNotify(false, daemon.SdNotifyWatchdog) every
  23. // time / 2.
  24. // If `unsetEnvironment` is true, the environment variables `WATCHDOG_USEC` and
  25. // `WATCHDOG_PID` will be unconditionally unset.
  26. //
  27. // It returns one of the following:
  28. // (0, nil) - watchdog isn't enabled or we aren't the watched PID.
  29. // (0, err) - an error happened (e.g. error converting time).
  30. // (time, nil) - watchdog is enabled and we can send ping.
  31. // time is delay before inactive service will be killed.
  32. func SdWatchdogEnabled(unsetEnvironment bool) (time.Duration, error) {
  33. wusec := os.Getenv("WATCHDOG_USEC")
  34. wpid := os.Getenv("WATCHDOG_PID")
  35. if unsetEnvironment {
  36. wusecErr := os.Unsetenv("WATCHDOG_USEC")
  37. wpidErr := os.Unsetenv("WATCHDOG_PID")
  38. if wusecErr != nil {
  39. return 0, wusecErr
  40. }
  41. if wpidErr != nil {
  42. return 0, wpidErr
  43. }
  44. }
  45. if wusec == "" {
  46. return 0, nil
  47. }
  48. s, err := strconv.Atoi(wusec)
  49. if err != nil {
  50. return 0, fmt.Errorf("error converting WATCHDOG_USEC: %s", err)
  51. }
  52. if s <= 0 {
  53. return 0, fmt.Errorf("error WATCHDOG_USEC must be a positive number")
  54. }
  55. interval := time.Duration(s) * time.Microsecond
  56. if wpid == "" {
  57. return interval, nil
  58. }
  59. p, err := strconv.Atoi(wpid)
  60. if err != nil {
  61. return 0, fmt.Errorf("error converting WATCHDOG_PID: %s", err)
  62. }
  63. if os.Getpid() != p {
  64. return 0, nil
  65. }
  66. return interval, nil
  67. }