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
|
title: State Retention
parent: Documentation
---
# State Retention Routines
_Ton Voon, June 16, 2010_
The aim is to create a set of library routines that can be used for saving
state information between invocations of a plugin. This way, it is possible
to calculate the rate of change and provide threshold calculations on this,
rather than just the current state.
This is based on a patch submitted by Alain Williams,
Nagios::Plugin::Differences by Jose Luis Martinez and comments on the mailing
list (see [references](#references)).
Lots of discussion between Holger and I ended up with this.
## Terms
**Location**
: Use `./configure` `--sharedstatedir` to define, default `$PREFIX/var`.
Override with `MP_STATE_PATH` envvar at runtime if set.
Add plugin name to end.
**Key**
: Is used as the filename of the store. Default to `state.dat`. Recommend
that this is set to the string returned by `np_state_generate_key()`, to
be unique per plugin call. Key can only consist of alphanumerics and
underscore.
## Format
Example format:
# NP state file
1 [file format version]
{data version}
{time}
{data}
## Structs
### np\_state\_key
char *name
char *plugin_name
int data_version
char *_filename
### np\_state\_data
time_t time
void *data
int length (of binary data)
## Calls
### np\_state\_generate\_key(argv)
Returns a string to use as a `key_name`, based on an MD5 hash of `argv`, thus
hopefully a unique key per service/plugin invocation. Use the
[Extra-Opts][extra-opts] parse of `argv`, so that uniqueness in parameters are
reflected there.
### np\_state\_init(plugin\_name, key\_name, data\_version)
Sets variables. Generates filename. Returns `np_state_key`. Die with
`UNKNOWN` if exception.
### np\_state\_read(np\_state\_key)
Returns `np_state_data`. Will return `NULL` if no data is available (first
run). If key currently exists, read data. If state file format version is
not expected, return as if no data. Get state data version number and compare
to expected. If numerically lower, then return as no previous state. Die
with `UNKNOWN` if exceptional error.
### np\_state\_write\_string(np\_state\_key, time, string)
If `time==NULL`, use current time. Create state file, with state file format
version, default text. Write version, time, and data. Avoid locking problems
- use `mv` to write and then swap. Possible loss of state data if two things
writing to same key at same time.
### np\_state\_write\_binary(np\_state\_key, time, start, length)
Same as `np_state_write_string()`, but writes binary data.
### np\_state\_data\_cleanup(np\_state\_data)
Cleanup.
### np\_state\_key\_cleanup(np\_state\_key)
Cleanup.
## Notes
- All opens and close within these functions, retaining atomicity.
- Libtap tests for library.
- Update [Development Guidelines][guidelines] with library usage.
- This has problems if a remote host is checked from different Nagios
instances.
- Binary data may not restore on a program compiled with different options
from the program that saved it; e.g., 32 or 64 bit.
- Binary data may include a structure containing a pointer. Pointer values
may not be used in the reading program - i.e., you need to overwrite the
value with something `malloc()`ed in the current run of the program.
- State files could be left lying around. We recommend you run a regular job
to remove unmodified state files older than 1 week.
## References
- <https://www.monitoring-plugins.org/archive/devel/2009-September/007767.html>
for the initial patch.
- <https://www.monitoring-plugins.org/archive/devel/2009-September/thread.html#7773>
for a conversation about the patch.
- <https://www.monitoring-plugins.org/archive/devel/2009-September/007749.html>
for Nagios::Plugin::Differences.
[extra-opts]: doc/extra-opts.html "Extra-Opts"
[guidelines]: doc/guidelines.html "Monitoring Plugin Development Guidelines"
<!--% # vim:set filetype=markdown textwidth=78 joinspaces expandtab: # %-->
|