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} |