summaryrefslogtreecommitdiff
path: root/sysutils/ups-nut/patches/patch-ab
blob: 467e3cf4ee6d2e0ff6b7b78559d204b15be0f8bb (plain)
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
$NetBSD: patch-ab,v 1.12 2013/02/16 17:34:58 jdf Exp $

Keep trying initialisation if we get a timeout or network error while
probing the device.
Submitted upstream as tracker #313195

--- drivers/snmp-ups.c.orig	2013-02-08 15:39:09.000000000 +0100
+++ drivers/snmp-ups.c	2013-02-08 15:39:13.000000000 +0100
@@ -90,6 +90,9 @@
 const char *mibname;
 const char *mibvers;
 
+int nut_snmp_err; /* saved snmp error from nut_snmp_get */
+int nut_sys_err; /* saved system errno from nut_snmp_get */
+
 static void disable_transfer_oids(void);
 
 #define DRIVER_NAME	"Generic SNMP UPS driver"
@@ -266,15 +269,15 @@
 
 	/* FIXME: first test if the device is reachable to avoid timeouts! */
 
-	/* Load the SNMP to NUT translation data */
-	load_mib2nut(mibs);
-
 	/* init polling frequency */
 	if (getval(SU_VAR_POLLFREQ))
 		pollfreq = atoi(getval(SU_VAR_POLLFREQ));
 	else
 		pollfreq = DEFAULT_POLLFREQ;
 
+	/* Load the SNMP to NUT translation data */
+	load_mib2nut(mibs);
+
 	/* Get UPS Model node to see if there's a MIB */
 	su_info_p = su_find_info("ups.model");
 	status = nut_snmp_get_str(su_info_p->OID, model, sizeof(model), NULL);
@@ -477,6 +480,9 @@
 	size_t name_len = MAX_OID_LEN;
 	static unsigned int numerr = 0;
 
+	nut_sys_err = 0;
+	nut_snmp_err = 0;
+
 	upsdebugx(3, "nut_snmp_get(%s)", OID);
 
 	/* create and send request. */
@@ -495,8 +501,10 @@
 
 	status = snmp_synch_response(g_snmp_sess_p, pdu, &response);
 
-	if (!response)
+	if (!response) {
+		snmp_error(g_snmp_sess_p, &nut_sys_err, &nut_snmp_err, NULL);
 		return NULL;
+	}
 
 	if (!((status == STAT_SUCCESS) && (response->errstat == SNMP_ERR_NOERROR)))
 	{
@@ -876,6 +884,7 @@
 bool_t load_mib2nut(const char *mib)
 {
 	int	i;
+	int snmp_timeout = 0;
 	char	buf[LARGEBUF];
 	mib2nut_info_t *m2n = NULL;
 
@@ -893,6 +902,7 @@
 	/* Otherwise, revert to the classic method */
 	if (m2n == NULL)
 	{
+again:
 		for (i = 0; mib2nut[i] != NULL; i++) {
 			/* Is there already a MIB name provided? */
 			if (strcmp(mib, "auto") && strcmp(mib, mib2nut[i]->mib_name)) {
@@ -902,6 +912,9 @@
 
 			/* Classic method: test an OID specific to this MIB */
 			if (!nut_snmp_get_str(mib2nut[i]->oid_auto_check, buf, sizeof(buf), NULL)) {
+				if (nut_snmp_err == SNMPERR_BAD_SENDTO ||
+					nut_snmp_err == SNMPERR_TIMEOUT)
+					snmp_timeout++;
 				continue;
 			}
 			/* MIB found */
@@ -920,6 +933,19 @@
 		upsdebugx(1, "load_mib2nut: using %s mib", mibname);
 		return TRUE;
 	}
+	if (snmp_timeout > 0) {
+		upslogx(LOG_WARNING, "timeout while probing %s",
+		    upsname?upsname:device_name);
+		snmp_timeout = 0;
+		if (sleep(pollfreq) == 0) {
+			/*
+			 * we're likely to end up in background if started
+			 * from upsdrvctl so enable syslog now
+			 */
+			syslogbit_set();
+			goto again;
+		}
+	}
 
 	/* Did we find something or is it really an unknown mib */
 	if (strcmp(mib, "auto") != 0) {