-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcheck_hwclock
More file actions
217 lines (176 loc) · 6.86 KB
/
Copy pathcheck_hwclock
File metadata and controls
217 lines (176 loc) · 6.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/env python3
#-------------------------------------------------------------------------------
import argparse
import time
import datetime
import os
import sys
#-------------------------------------------------------------------------------
_candebug = False
def candebug():
global _candebug
return _candebug
def setcandebug(value):
global _candebug
_candebug = value
def infomsg(msg):
if candebug() == True:
print(msg, flush=True)
def mapstatustoexitcode(status):
if status=="OK":
exitcode = 0
elif status=="WARNING":
exitcode = 1
elif status=="CRITICAL":
exitcode = 2
elif status=="UNKNOWN":
exitcode = 3
else:
exitcode = 4
return exitcode
def exitnagios(status,message):
exitcode = mapstatustoexitcode(status)
print(status+": "+message, flush=True)
sys.exit(exitcode)
#-------------------------------------------------------------------------------
def list_rtc_devices():
rtc_path = "/sys/class/rtc"
devices = []
if os.path.exists(rtc_path):
for entry in os.listdir(rtc_path):
if entry.startswith("rtc") and entry != "rtc":
devices.append(entry)
return devices
def read_rtc(rtc_name):
if rtc_name.startswith("/sys/class/rtc/"):
rtc_device = rtc_name
else:
rtc_device = "/sys/class/rtc/" + rtc_name
time_file = rtc_device + "/time"
date_file = rtc_device + "/date"
if not os.path.exists(time_file) or not os.path.exists(date_file):
return (None, None)
f_time = None
f_date = None
time_str = None
date_str = None
# Read time
try:
f_time = open(time_file, "r")
time_str = f_time.read().strip()
except:
pass
finally:
if f_time is not None:
f_time.close()
# Read date
try:
f_date = open(date_file, "r")
date_str = f_date.read().strip()
except:
pass
finally:
if f_date is not None:
f_date.close()
return (date_str, time_str)
def check_rtc_device(rtc_name):
date1, time1 = read_rtc(rtc_name)
if date1 is None or time1 is None:
return False
time.sleep(2)
date2, time2 = read_rtc(rtc_name)
if date2 is None or time2 is None:
return False
if date1 != date2 or time1 != time2:
return True
else:
return False
def finddevice():
alldevices = list_rtc_devices()
infomsg("The list of found devices is "+str(alldevices))
if len(alldevices)==0:
return None
else:
for device in alldevices:
valid = check_rtc_device(device)
if valid:
return device
return None
#-------------------------------------------------------------------------------
def check_rtc_utc():
adjfilename = "/etc/adjtime"
if os.path.isfile(adjfilename)==True:
filehandle = open(adjfilename,"rt")
hwclockdata = filehandle.read().splitlines()
filehandle.close()
is_rtc_utc = (hwclockdata[2].strip().upper() == "UTC")
if is_rtc_utc == False:
exitnagios("CRITICAL","hwclock is not UTC")
def get_rtc_data(device):
# Validate device
rtc_sys_path = f"/sys/class/rtc/{device}"
if not os.path.exists(rtc_sys_path):
exitnagios("CRITICAL", f"{device} does not exist on this system")
try:
# Read date
with open(os.path.join(rtc_sys_path, "date"), "rt") as f:
date_str = f.read().strip() # format: YYYY-MM-DD
# Read time
with open(os.path.join(rtc_sys_path, "time"), "rt") as f:
time_str = f.read().strip() # format: HH:MM:SS
# Optional: check battery status
batt_file = os.path.join(rtc_sys_path, "batt_status")
if os.path.exists(batt_file):
with open(batt_file, "rt") as f:
batt_status = f.read().strip()
if batt_status != "okay":
exitnagios("CRITICAL", f"RTC battery not valid for {device}")
# Parse date and time
date_parts = date_str.split("-")
time_parts = time_str.split(":")
if len(date_parts) != 3 or len(time_parts) != 3:
exitnagios("CRITICAL", f"Could not parse RTC data for {device}")
rtctime = datetime.datetime(
int(date_parts[0]), int(date_parts[1]), int(date_parts[2]),
int(time_parts[0]), int(time_parts[1]), int(time_parts[2]),
tzinfo=datetime.timezone.utc
)
return int(rtctime.timestamp())
except Exception as e:
exitnagios("CRITICAL", f"Error reading RTC data for {device}: {e}")
#-------------------------------------------------------------------------------
def parse_args(forcedargs=None):
parser = argparse.ArgumentParser()
parser.add_argument("-w", "--warning", action="store", type=int, default=5, help="if this number or more, it becomes warning state (default 5")
parser.add_argument("-c", "--critical", action="store", type=int, default=10, help="if this number or more, it becomes critical state (default 10")
parser.add_argument("-t", "--timeout", action="store", type=int, default=90, help="seconds to wait before timeout, default 90; SKY each min it should be over 60")
parser.add_argument("-®", "--debug", action="store_true", dest="debug", default=False, help="be more verbose")
args = parser.parse_args(forcedargs)
return args
def evaluate(device,difference,warning,critical):
if (difference>=critical):
exitnagios("CRITICAL","The hwclock offset using device "+device+" is "+str(difference)+"s | difference="+str(difference))
elif (difference>=warning):
exitnagios("WARNING","The hwclock offset using device "+device+" is "+str(difference)+"s | difference="+str(difference))
else:
exitnagios("OK","The hwclock offset using device "+device+" is "+str(difference)+"s | difference="+str(difference))
def main(forcedargs=None):
args = parse_args(forcedargs)
setcandebug(args.debug)
device = finddevice()
if device == None:
exitnagios("CRITICAL","Could not find any rtc device")
else:
infomsg("The selected rtc device is "+device)
check_rtc_utc()
rtctime = get_rtc_data(device)
infomsg(rtctime)
systime = int(time.time())
infomsg(systime)
difference = abs(rtctime - systime)
evaluate(device,difference,args.warning,args.critical)
exitnagios("CRITICAL","Internal error")
#-------------------------------------------------------------------------------
if __name__ == "__main__":
main()
#-------------------------------------------------------------------------------