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