1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2009-2016 OpenWrt.org
3 # Copyright (C) 2016 Luke McKee <hojuruku@gmail.com>
4 # Procd init script reference: http://wiki.prplfoundation.org/wiki/Procd_reference
8 PROG
=/usr
/bin
/mini_snmpd
11 global_respawn_threshold
=
12 global_respawn_timeout
=
16 logger
-p daemon.info
-t mini_snmpd
"$@"
20 logger
-p daemon.err
-t mini_snmpd
"$@"
24 # mini_snmpd 1.3+ now starts later in the game. Expects filesystems monitored to be already mounted, or wont pass args to mini_snmpd
25 # and at least configuration entry for network physical interface defined in /etc/config/network
26 # It handles network interfaces not yet present (e.g. ppp) but will statfs() the root/wrong filesystem if device not mounted
27 # Tip: complex scripts run faster without in openwrt if you stop busybox forking and searching for applets. Faster bootups
28 # CONFIG_BUSYBOX_CONFIG_FEATURE_SH_NOFORK
29 # CONFIG_BUSYBOX_CONFIG_FEATURE_PREFER_APPLETS
30 # BUSYBOX_CONFIG_ASH_OPTIMIZE_FOR_SIZE [=n]
31 # CONFIG_BUSYBOX_CONFIG_ASH_CMDCMD
33 mini_snmpd_validation
="enabled:bool:0 \
37 community:rangelength(1,32):public \
38 contact:maxlength(255) \
39 description:maxlength(255) \
40 location:maxlength(255) \
41 listen_interface:uciname \
45 mib_timeout:and(min(1),uinteger) \
46 disks:list(directory) \
47 interfaces:list(uciname) \
48 respawn_threshold:uinteger respawn_timeout:uinteger respawn_retry:uinteger"
49 # busybox ash has no array variable support, when put validations in a string be careful to have no spaces in each validate constraint
50 # this makes it very difficult to use the 'or(uciname, "all")' test, so listen_interface '' or undefined now meands bind to "all".
51 # this is the sarafice you have to make to avoid typing it all in twice in this script so we can give feedback to user on what's misconfigered
55 local disk
="$1" disk_count
56 [ -z $disk_count ] && disk_count
=0
57 if grep -qF "$disk" /proc
/mounts
; then
58 # check the fileystem is mountpoint, and directory search permissions available for statfs()
59 # presence as a directory -d test done is already done by uci_validate_section()
61 _err
"$cfg: mountpoint $disk for snmp monitoring EACCES error. Check permissions, ignoring"
64 if [ $disk_count -lt 4 ]; then
65 append disks_arg
"$disk" ','
66 disk_count
=$
((disk_count
++))
68 _err
"$cfg: more than 4 mountpoints defined in uci. Disc $disk ignored."
71 _err
"$cfg: mountpoint $disk for snmp monitoring not mounted, ignoring."
76 local name
="$1" netdev netdev_count
77 [ -z $netdev_count ] && netdev_count
=0
78 # for the purposes of snmp monitoring it doesn't need to be up, it just needs to exist in /proc/net/dev
79 network_get_device netdev
"$name"
80 if [ -n "$netdev" ] && grep -qF "$netdev" /proc
/net
/dev
; then
81 [ $netdev_count -ge 8 ] && {
82 _err
"$cfg: too many network interfaces configured, ignoring $name"
85 netdev_count
=$
((netdev_count
++))
86 if [ -n "$interfaces_arg" ]; then
87 append interfaces_arg
"$netdev" ','
89 append interfaces_arg
"$netdev"
92 _log
"$cfg: physical interface for network $name not found in uci or kernel so not monitoring"
99 [ -n "$var" ] && procd_append_param
command $opt "$var"
104 local enabled listen_interface
# listen_interface_up
105 config_get_bool enabled
"$cfg" "enabled" '1'
106 [ "$enabled" -gt 0 ] ||
return 0
107 config_get listen_interface
"$cfg" listen_interface
108 # If the interface is up & instance is running we'll watch at the instance level and only restart that instance if it's bound interface changes
109 # Regardless of ubus knowing about an interface (in the case it's not yet configured)
110 [ -n "$listen_interface" ] && trigger_interfaces
="$listen_interface $trigger_interfaces"
111 # Restart daemon if one of monitored interfaces changes
112 config_get reload_interfaces
"$cfg" interfaces
115 validate_mini_snmpd_section
() {
116 # validate a mini_snmpd instance in uci config file mini_snmpd
117 # http://luci.subsignal.org/trac/wiki/Documentation/Datatypes ubox/validate/validate.c
118 uci_load_validate mini_snmpd mini_snmpd
"$1" "$2" $mini_snmpd_validation
123 config_load
'mini_snmpd'
125 procd_add_config_trigger
"config.change" "mini_snmpd" /etc
/init.d
/mini_snmpd reload
126 config_foreach watch_interfaces
'mini_snmpd'
127 # this only watches interfaces for which there is no running instance due to interface down / not in ubus
128 # hence start not reload, this trigger will not affect running instances as another start will not change their procd command arguments
129 # or stop the already running process
130 [ -n "$trigger_interfaces" ] && {
131 for n
in $trigger_interfaces; do
132 procd_add_interface_trigger
"interface.*" $n /etc
/init.d
/mini_snmpd start
135 [ -n "$reload_interfaces" ] && {
136 for n
in $reload_interfaces; do
137 procd_add_reload_interface_trigger
$n
141 procd_add_validation validate_mini_snmpd_section
146 local cfg validation_failed validation_err disks_arg interfaces_arg
148 [ "$2" = 0 ] || validation_failed
=1
149 [ "$enabled" == 1 ] ||
{
150 _log
"instance:$cfg disabled not starting"
154 local listen_interface_json listen_interface_ip listen_interface_device listen_interface_up
155 [ -n "$listen_interface" ] && {
156 if [ "$ipv6" = 1 ]; then
157 network_get_ipaddrs6 listen_interface_ip
"$listen_interface"
159 network_get_ipaddrs listen_interface_ip
"$listen_interface"
161 network_is_up
"$listen_interface" && [ -n "$listen_interface_ip" ] ||
{
162 _log
"$cfg:listen interface $listen_interface not up yet / not configured properly"
163 _log
"$cfg:procd will try again when interface state changes"
166 network_get_physdev listen_interface_device
"$listen_interface"
169 [ $validation_failed ] && {
170 _err
"validation of $NAME configuration for $cfg instance failed, all tests should be within constraints"
171 _err
"please edit the configuration values below using [l]uci "
172 validation_err
=`/sbin/validate_data mini_snmpd mini_snmpd "$cfg" $mini_snmpd_validation 2>&1 | sed '/with\ false$/!d;s/validates\ as\ /needs\ to\ be\ /;s/with\ false//' `
173 _err
"$validation_err"
176 config_list_foreach
"$cfg" 'disks' append_disk
177 config_list_foreach
"$cfg" 'interfaces' append_interface
178 # test if variables are unset or zero length
179 [ -z "${disks_arg:+1}" -a -z "${interfaces_arg:+1}" ] && {
180 _err
"$cfg: you haven't sucessfully configured any mountpoints or disks for this instance, not starting"
184 [ -z "$respawn_threshold$respawn_timeout$respawn_retry" ] && {
185 respawn_threshold
=$global_respawn_threshold
186 respawn_timeout
=$global_respawn_timeout
187 respawn_retry
=$global_respawn_retry
189 [ -z "$global_respawn_threshold$global_respawn_timeout$global_respawn_retry" ] && {
190 global_respawn_threshold
=$respawn_threshold
191 global_respawn_timeout
=$respawn_timeout
192 global_respawn_retry
=$respawn_retry
197 procd_set_param
command "$PROG" -n
198 procd_set_param stdout
"1"
199 procd_set_param stderr
"1"
200 # don't the like default respawn values? you can override through uci.
201 # vars saved as global so you only need to do it in the first mini_snmpd instance
202 procd_set_param respawn
${respawn_threshold:-3600} ${respawn_timeout:-10} ${respawn_retry:-1}
203 # this monitors ubus changes
204 [ -n "$listen_interface" ] && {
206 #procd_add_interface_trigger "interface.*" $listen_interface /etc/init.d/mini_snmpd reload
208 procd_add_reload_interface_trigger
$listen_interface #or use shorthand of above
210 # this re-starts the daemon if a properly configured network interface is changed whilst it is already running
211 # igmpproxy has this as well as "procd_set_param netdev"
213 append_arg
"-c" "$community"
214 append_arg
"-L" "$location"
215 append_arg
"-C" "$contact"
216 append_arg
"-D" "$description"
217 append_arg
"-p" $udp_port
218 append_arg
"-P" $tcp_port
219 append_arg
"-V" "$vendor_oid"
220 append_arg
"-t" $mib_timeout
222 [ "$ipv6" = 1 ] && procd_append_param
command "-6"
223 [ "$debug" = 1 ] && procd_append_param
command "-v"
224 # uci_validate_section() aka /sbin/validate_data can only cast default values not defined in /etc/config/* to string
225 # e.g. ="1" however it sets bools defined in /etc/config/* to =1 / =0
226 [ "$auth" = 1 -o "$auth" = "1" ] && procd_append_param
command "-a"
227 [ -n "$disks_arg" ] && procd_append_param
command "-d" "$disks_arg"
228 [ -n "$interfaces_arg" ] && {
229 procd_append_param netdev
${interfaces_arg//,/ }
230 procd_append_param
command "-i" "$interfaces_arg"
232 [ -n "$listen_interface_device" ] && {
233 procd_append_param
command "-I" "$listen_interface_device"
234 # and this monitors the hardware device for changes outside of ubus - just a guess
235 procd_append_param netdev
$listen_interface_device
242 .
/lib
/functions
/network.sh
244 config_load
'mini_snmpd'
245 config_foreach validate_mini_snmpd_section
'mini_snmpd' start_instance