Deleted Added
full compact
hostres_device_tbl.c (154137) hostres_device_tbl.c (160341)
1 /*-
2 * Copyright (c) 2005-2006 The FreeBSD Project
3 * All rights reserved.
4 *
5 * Author: Victor Cruceru <soc-victor@freebsd.org>
6 *
7 * Redistribution of this software and documentation and use in source and
8 * binary forms, with or without modification, are permitted provided that

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1 /*-
2 * Copyright (c) 2005-2006 The FreeBSD Project
3 * All rights reserved.
4 *
5 * Author: Victor Cruceru <soc-victor@freebsd.org>
6 *
7 * Redistribution of this software and documentation and use in source and
8 * binary forms, with or without modification, are permitted provided that

--- 12 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c 154133 2006-01-09 12:33:45Z harti $
29 * $FreeBSD: head/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c 160341 2006-07-14 09:07:56Z harti $
30 */
31
32/*
33 * Host Resources MIB: hrDeviceTable implementation for SNMPd.
34 */
35
36#include <sys/un.h>
37#include <sys/limits.h>
38
39#include <assert.h>
40#include <err.h>
41#include <errno.h>
42#include <stdlib.h>
43#include <string.h>
44#include <syslog.h>
45#include <unistd.h>
30 */
31
32/*
33 * Host Resources MIB: hrDeviceTable implementation for SNMPd.
34 */
35
36#include <sys/un.h>
37#include <sys/limits.h>
38
39#include <assert.h>
40#include <err.h>
41#include <errno.h>
42#include <stdlib.h>
43#include <string.h>
44#include <syslog.h>
45#include <unistd.h>
46#include <sysexits.h>
46
47#include "hostres_snmp.h"
48#include "hostres_oid.h"
49#include "hostres_tree.h"
50
47
48#include "hostres_snmp.h"
49#include "hostres_oid.h"
50#include "hostres_tree.h"
51
52#define FREE_DEV_STRUCT(entry_p) do { \
53 free(entry_p->name); \
54 free(entry_p->location); \
55 free(entry_p->descr); \
56 free(entry_p); \
57} while (0)
58
51/*
52 * Status of a device
53 */
54enum DeviceStatus {
55 DS_UNKNOWN = 1,
56 DS_RUNNING = 2,
57 DS_WARNING = 3,
58 DS_TESTING = 4,

--- 28 unchanged lines hidden (view full) ---

87static const struct asn_oid OIDX_hrDeviceOther_c = OIDX_hrDeviceOther;
88
89/**
90 * Create a new entry out of thin air.
91 */
92struct device_entry *
93device_entry_create(const char *name, const char *location, const char *descr)
94{
59/*
60 * Status of a device
61 */
62enum DeviceStatus {
63 DS_UNKNOWN = 1,
64 DS_RUNNING = 2,
65 DS_WARNING = 3,
66 DS_TESTING = 4,

--- 28 unchanged lines hidden (view full) ---

95static const struct asn_oid OIDX_hrDeviceOther_c = OIDX_hrDeviceOther;
96
97/**
98 * Create a new entry out of thin air.
99 */
100struct device_entry *
101device_entry_create(const char *name, const char *location, const char *descr)
102{
95 struct device_entry *entry;
96 struct device_map_entry *map;
103 struct device_entry *entry = NULL;
104 struct device_map_entry *map = NULL;
105 size_t name_len;
106 size_t location_len;
97
98 assert((name[0] != 0) || (location[0] != 0));
99
100 if (name[0] == 0 && location[0] == 0)
101 return (NULL);
102
107
108 assert((name[0] != 0) || (location[0] != 0));
109
110 if (name[0] == 0 && location[0] == 0)
111 return (NULL);
112
103 if ((entry = malloc(sizeof(*entry))) == NULL) {
104 syslog(LOG_WARNING, "hrDeviceTable: %s: %m", __func__);
105 return (NULL);
106 }
107 memset(entry, 0, sizeof(*entry));
113 STAILQ_FOREACH(map, &device_map, link) {
114 assert(map->name_key != NULL);
115 assert(map->location_key != NULL);
108
116
109 STAILQ_FOREACH(map, &device_map, link)
110 if (strcmp(map->name_key, name) == 0 &&
111 strcmp(map->location_key, location) == 0) {
117 if (strcmp(map->name_key, name) == 0 &&
118 strcmp(map->location_key, location) == 0) {
112 entry->index = map->hrIndex;
113 map->entry_p = entry;
114 break;
115 }
119 break;
120 }
121 }
116
117 if (map == NULL) {
118 /* new object - get a new index */
119 if (next_device_index > INT_MAX) {
120 syslog(LOG_ERR,
121 "%s: hrDeviceTable index wrap", __func__);
122
123 if (map == NULL) {
124 /* new object - get a new index */
125 if (next_device_index > INT_MAX) {
126 syslog(LOG_ERR,
127 "%s: hrDeviceTable index wrap", __func__);
122 free(entry);
123 return (NULL);
128 /* There isn't much we can do here.
129 * If the next_swins_index is consumed
130 * then we can't add entries to this table
131 * So it is better to exit - if the table is sparsed
132 * at the next agent run we can fill it fully.
133 */
134 errx(EX_SOFTWARE, "hrDeviceTable index wrap");
135 /* not reachable */
124 }
125
126 if ((map = malloc(sizeof(*map))) == NULL) {
127 syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ );
136 }
137
138 if ((map = malloc(sizeof(*map))) == NULL) {
139 syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ );
128 free(entry);
129 return (NULL);
130 }
131
140 return (NULL);
141 }
142
132 map->hrIndex = next_device_index++;
143 map->entry_p = NULL;
133
144
134 strlcpy(map->name_key, name, sizeof(map->name_key));
135 strlcpy(map->location_key, location, sizeof(map->location_key));
145 name_len = strlen(name) + 1;
146 if (name_len > DEV_NAME_MLEN)
147 name_len = DEV_NAME_MLEN;
136
148
137 map->entry_p = entry;
149 if ((map->name_key = malloc(name_len)) == NULL) {
150 syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ );
151 free(map);
152 return (NULL);
153 }
138
154
155 location_len = strlen(location) + 1;
156 if (location_len > DEV_LOC_MLEN)
157 location_len = DEV_LOC_MLEN;
158
159 if ((map->location_key = malloc(location_len )) == NULL) {
160 syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ );
161 free(map->name_key);
162 free(map);
163 return (NULL);
164 }
165
166 map->hrIndex = next_device_index++;
167
168 strlcpy(map->name_key, name, name_len);
169 strlcpy(map->location_key, location, location_len);
170
139 STAILQ_INSERT_TAIL(&device_map, map, link);
140 HRDBG("%s at %s added into hrDeviceMap at index=%d",
141 name, location, map->hrIndex);
142 } else {
143 HRDBG("%s at %s exists in hrDeviceMap index=%d",
144 name, location, map->hrIndex);
145 }
146
171 STAILQ_INSERT_TAIL(&device_map, map, link);
172 HRDBG("%s at %s added into hrDeviceMap at index=%d",
173 name, location, map->hrIndex);
174 } else {
175 HRDBG("%s at %s exists in hrDeviceMap index=%d",
176 name, location, map->hrIndex);
177 }
178
179 if ((entry = malloc(sizeof(*entry))) == NULL) {
180 syslog(LOG_WARNING, "hrDeviceTable: %s: %m", __func__);
181 return (NULL);
182 }
183 memset(entry, 0, sizeof(*entry));
184
147 entry->index = map->hrIndex;
185 entry->index = map->hrIndex;
186 map->entry_p = entry;
148
187
149 strlcpy(entry->name, name, sizeof(entry->name));
150 strlcpy(entry->location, location, sizeof(entry->location));
188 if ((entry->name = strdup(map->name_key)) == NULL) {
189 syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ );
190 free(entry);
191 return (NULL);
192 }
151
193
194 if ((entry->location = strdup(map->location_key)) == NULL) {
195 syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ );
196 free(entry->name);
197 free(entry);
198 return (NULL);
199 }
200
201 /*
202 * From here till the end of this function we reuse name_len
203 * for a diferrent purpose - for device_entry::descr
204 */
152 if (name[0] != '\0')
205 if (name[0] != '\0')
153 snprintf(entry->descr, sizeof(entry->descr), "%s: %s",
154 name, descr);
206 name_len = strlen(name) + strlen(descr) +
207 strlen(": ") + 1;
155 else
208 else
156 snprintf(entry->descr, sizeof(entry->descr),
209 name_len = strlen(location) + strlen(descr) +
210 strlen("unknown at : ") + 1;
211
212 if (name_len > DEV_DESCR_MLEN)
213 name_len = DEV_DESCR_MLEN;
214
215 if ((entry->descr = malloc(name_len )) == NULL) {
216 syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ );
217 free(entry->name);
218 free(entry->location);
219 free(entry);
220 return (NULL);
221 }
222
223 memset(&entry->descr[0], '\0', name_len);
224
225 if (name[0] != '\0')
226 snprintf(entry->descr, name_len,
227 "%s: %s", name, descr);
228 else
229 snprintf(entry->descr, name_len,
157 "unknown at %s: %s", location, descr);
158
230 "unknown at %s: %s", location, descr);
231
159 entry->id = oid_zeroDotZero; /* unknown id - FIXME */
160 entry->status = (u_int)DIS_ATTACHED;
232 entry->id = &oid_zeroDotZero; /* unknown id - FIXME */
233 entry->status = (u_int)DS_UNKNOWN;
161 entry->errors = 0;
234 entry->errors = 0;
162 entry->type = OIDX_hrDeviceOther_c;
235 entry->type = &OIDX_hrDeviceOther_c;
163
164 INSERT_OBJECT_INT(entry, &device_tbl);
165
166 return (entry);
167}
168
169/**
170 * Create a new entry into the device table.

--- 7 unchanged lines hidden (view full) ---

178
179 return (device_entry_create(dev_p->dd_name, dev_p->dd_location,
180 dev_p->dd_desc));
181}
182
183/**
184 * Delete an entry from the device table.
185 */
236
237 INSERT_OBJECT_INT(entry, &device_tbl);
238
239 return (entry);
240}
241
242/**
243 * Create a new entry into the device table.

--- 7 unchanged lines hidden (view full) ---

251
252 return (device_entry_create(dev_p->dd_name, dev_p->dd_location,
253 dev_p->dd_desc));
254}
255
256/**
257 * Delete an entry from the device table.
258 */
186static void
259void
187device_entry_delete(struct device_entry *entry)
188{
189 struct device_map_entry *map;
190
191 assert(entry != NULL);
192
193 TAILQ_REMOVE(&device_tbl, entry, link);
194
195 STAILQ_FOREACH(map, &device_map, link)
196 if (map->entry_p == entry) {
197 map->entry_p = NULL;
198 break;
199 }
260device_entry_delete(struct device_entry *entry)
261{
262 struct device_map_entry *map;
263
264 assert(entry != NULL);
265
266 TAILQ_REMOVE(&device_tbl, entry, link);
267
268 STAILQ_FOREACH(map, &device_map, link)
269 if (map->entry_p == entry) {
270 map->entry_p = NULL;
271 break;
272 }
200 free(entry);
273
274 FREE_DEV_STRUCT(entry);
201}
202
203/**
204 * Find an entry given its name and location
205 */
206static struct device_entry *
207device_find_by_dev(const struct devinfo_dev *dev_p)
208{

--- 38 unchanged lines hidden (view full) ---

247
248 return (NULL);
249}
250
251/**
252 * Find out the type of device. CPU only currently.
253 */
254static void
275}
276
277/**
278 * Find an entry given its name and location
279 */
280static struct device_entry *
281device_find_by_dev(const struct devinfo_dev *dev_p)
282{

--- 38 unchanged lines hidden (view full) ---

321
322 return (NULL);
323}
324
325/**
326 * Find out the type of device. CPU only currently.
327 */
328static void
255device_get_type(struct devinfo_dev *dev_p, struct asn_oid *out_type_p)
329device_get_type(struct devinfo_dev *dev_p, const struct asn_oid **out_type_p)
256{
257
258 assert(dev_p != NULL);
259 assert(out_type_p != NULL);
260
261 if (dev_p == NULL)
262 return;
263
264 if (strncmp(dev_p->dd_name, "cpu", strlen("cpu")) == 0 &&
265 strstr(dev_p->dd_location, ".CPU") != NULL) {
330{
331
332 assert(dev_p != NULL);
333 assert(out_type_p != NULL);
334
335 if (dev_p == NULL)
336 return;
337
338 if (strncmp(dev_p->dd_name, "cpu", strlen("cpu")) == 0 &&
339 strstr(dev_p->dd_location, ".CPU") != NULL) {
266 *out_type_p = OIDX_hrDeviceProcessor_c;
340 *out_type_p = &OIDX_hrDeviceProcessor_c;
267 return;
268 }
269}
270
271/**
272 * Get the status of a device
273 */
274static enum DeviceStatus

--- 81 unchanged lines hidden (view full) ---

356 return (-1);
357 }
358
359 return (d_sock);
360}
361
362/*
363 * Event on the devd socket.
341 return;
342 }
343}
344
345/**
346 * Get the status of a device
347 */
348static enum DeviceStatus

--- 81 unchanged lines hidden (view full) ---

430 return (-1);
431 }
432
433 return (d_sock);
434}
435
436/*
437 * Event on the devd socket.
364 **
438 *
365 * We should probably directly process entries here. For simplicity just
366 * call the refresh routine with the force flag for now.
367 */
368static void
369devd_socket_callback(int fd, void *arg __unused)
370{
371 char buf[512];
372 int read_len = -1;

--- 85 unchanged lines hidden (view full) ---

458 (void)close(devd_sock);
459
460 devinfo_free();
461
462 while ((n1 = STAILQ_FIRST(&device_map)) != NULL) {
463 STAILQ_REMOVE_HEAD(&device_map, link);
464 if (n1->entry_p != NULL) {
465 TAILQ_REMOVE(&device_tbl, n1->entry_p, link);
439 * We should probably directly process entries here. For simplicity just
440 * call the refresh routine with the force flag for now.
441 */
442static void
443devd_socket_callback(int fd, void *arg __unused)
444{
445 char buf[512];
446 int read_len = -1;

--- 85 unchanged lines hidden (view full) ---

532 (void)close(devd_sock);
533
534 devinfo_free();
535
536 while ((n1 = STAILQ_FIRST(&device_map)) != NULL) {
537 STAILQ_REMOVE_HEAD(&device_map, link);
538 if (n1->entry_p != NULL) {
539 TAILQ_REMOVE(&device_tbl, n1->entry_p, link);
466 free(n1->entry_p);
540 FREE_DEV_STRUCT(n1->entry_p);
467 }
541 }
542 free(n1->name_key);
543 free(n1->location_key);
468 free(n1);
469 }
470 assert(TAILQ_EMPTY(&device_tbl));
471}
472
473/**
474 * Refresh routine for hrDeviceTable. We don't refresh here if the devd socket
475 * is open, because in this case we have the actual information always. We

--- 109 unchanged lines hidden (view full) ---

585 get:
586 switch (value->var.subs[sub - 1]) {
587
588 case LEAF_hrDeviceIndex:
589 value->v.integer = entry->index;
590 return (SNMP_ERR_NOERROR);
591
592 case LEAF_hrDeviceType:
544 free(n1);
545 }
546 assert(TAILQ_EMPTY(&device_tbl));
547}
548
549/**
550 * Refresh routine for hrDeviceTable. We don't refresh here if the devd socket
551 * is open, because in this case we have the actual information always. We

--- 109 unchanged lines hidden (view full) ---

661 get:
662 switch (value->var.subs[sub - 1]) {
663
664 case LEAF_hrDeviceIndex:
665 value->v.integer = entry->index;
666 return (SNMP_ERR_NOERROR);
667
668 case LEAF_hrDeviceType:
593 value->v.oid = entry->type;
669 assert(entry->type != NULL);
670 value->v.oid = *(entry->type);
594 return (SNMP_ERR_NOERROR);
595
596 case LEAF_hrDeviceDescr:
597 return (string_get(value, entry->descr, -1));
598
599 case LEAF_hrDeviceID:
671 return (SNMP_ERR_NOERROR);
672
673 case LEAF_hrDeviceDescr:
674 return (string_get(value, entry->descr, -1));
675
676 case LEAF_hrDeviceID:
600 value->v.oid = entry->id;
677 value->v.oid = *(entry->id);
601 return (SNMP_ERR_NOERROR);
602
603 case LEAF_hrDeviceStatus:
604 value->v.integer = entry->status;
605 return (SNMP_ERR_NOERROR);
606
607 case LEAF_hrDeviceErrors:
608 value->v.uint32 = entry->errors;
609 return (SNMP_ERR_NOERROR);
610 }
611 abort();
612}
678 return (SNMP_ERR_NOERROR);
679
680 case LEAF_hrDeviceStatus:
681 value->v.integer = entry->status;
682 return (SNMP_ERR_NOERROR);
683
684 case LEAF_hrDeviceErrors:
685 value->v.uint32 = entry->errors;
686 return (SNMP_ERR_NOERROR);
687 }
688 abort();
689}