watchdog.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  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 return watchdog information for a service.
  22. // Process should send daemon.SdNotify("WATCHDOG=1") every time / 2.
  23. // If `unsetEnvironment` is true, the environment variables `WATCHDOG_USEC`
  24. // and `WATCHDOG_PID` will be unconditionally unset.
  25. //
  26. // It returns one of the following:
  27. // (0, nil) - watchdog isn't enabled or we aren't the watched PID.
  28. // (0, err) - an error happened (e.g. error converting time).
  29. // (time, nil) - watchdog is enabled and we can send ping.
  30. // time is delay before inactive service will be killed.
  31. func SdWatchdogEnabled(unsetEnvironment bool) (time.Duration, error) {
  32. wusec := os.Getenv("WATCHDOG_USEC")
  33. wpid := os.Getenv("WATCHDOG_PID")
  34. if unsetEnvironment {
  35. wusecErr := os.Unsetenv("WATCHDOG_USEC")
  36. wpidErr := os.Unsetenv("WATCHDOG_PID")
  37. if wusecErr != nil {
  38. return 0, wusecErr
  39. }
  40. if wpidErr != nil {
  41. return 0, wpidErr
  42. }
  43. }
  44. if wusec == "" {
  45. return 0, nil
  46. }
  47. s, err := strconv.Atoi(wusec)
  48. if err != nil {
  49. return 0, fmt.Errorf("error converting WATCHDOG_USEC: %s", err)
  50. }
  51. if s <= 0 {
  52. return 0, fmt.Errorf("error WATCHDOG_USEC must be a positive number")
  53. }
  54. interval := time.Duration(s) * time.Microsecond
  55. if wpid == "" {
  56. return interval, nil
  57. }
  58. p, err := strconv.Atoi(wpid)
  59. if err != nil {
  60. return 0, fmt.Errorf("error converting WATCHDOG_PID: %s", err)
  61. }
  62. if os.Getpid() != p {
  63. return 0, nil
  64. }
  65. return interval, nil
  66. }