Date: Sat, 3 Jun 2006 15:57:36 GMT From: Shteryana Shopova <shteryana@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 98397 for review Message-ID: <200606031557.k53Fva0S048290@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=98397 Change 98397 by shteryana@prometheus on 2006/06/03 15:56:40 sync SoC2005 branch with head - snmp_hostres code was mismerged during previous integration Affected files ... .. //depot/projects/soc2005/bsnmp/contrib/bsnmp/snmpd/snmpd.h#3 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#25 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c#13 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c#15 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c#9 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_network_tbl.c#8 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c#7 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_printer_tbl.c#8 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_processor_tbl.c#6 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c#13 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c#24 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h#29 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c#13 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swinstalled_tbl.c#5 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrun_tbl.c#9 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrunperf_tbl.c#3 delete .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_tree.def#3 edit Differences ... ==== //depot/projects/soc2005/bsnmp/contrib/bsnmp/snmpd/snmpd.h#3 (text+ko) ==== @@ -92,8 +92,6 @@ void *udata; /* user data */ evTimerID id; /* timer id */ struct lmodule *owner; /* owner of the timer */ - int periodic; /* flag to track periodic timers, 0 for one shot, - 1 for periodic timers*/ LIST_ENTRY(timer) link; }; ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#25 (text+ko) ==== @@ -1,5 +1,5 @@ -# -# Copyright (c) 2005 The FreeBSD Project +# +# Copyright (c) 2005-2006 The FreeBSD Project # All rights reserved. # Author: Victor Cruceru <soc-victor@freebsd.org> # @@ -25,27 +25,30 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # +# $FreeBSD: src/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile,v 1.3 2006/01/26 10:13:32 harti Exp $ +# -CONTRIB=${.CURDIR}/../../../../contrib/bsnmp +LPRSRC= ${.CURDIR}/../../../lpr/common_source +.PATH: ${LPRSRC} MOD= hostres -SRCS= hostres_snmp.c \ - hostres_scalars.c \ - hostres_storage_tbl.c \ - hostres_fs_tbl.c \ - hostres_swrun_tbl.c\ - hostres_swrunperf_tbl.c \ - hostres_device_tbl.c \ - hostres_processor_tbl.c \ - hostres_diskstorage_tbl.c \ - hostres_partition_tbl.c \ - hostres_network_tbl.c \ - hostres_swinstalled_tbl.c \ - hostres_printer_tbl.c - -WARNS?= 3 +SRCS= hostres_begemot.c \ + hostres_device_tbl.c \ + hostres_diskstorage_tbl.c \ + hostres_fs_tbl.c \ + hostres_network_tbl.c \ + hostres_partition_tbl.c \ + hostres_printer_tbl.c \ + hostres_processor_tbl.c \ + hostres_scalars.c \ + hostres_snmp.c \ + hostres_storage_tbl.c \ + hostres_swinstalled_tbl.c \ + hostres_swrun_tbl.c \ + printcap.c + #Not having NDEBUG defined will enable assertions and a lot of output on stderr -CFLAGS+= -DNDEBUG +CFLAGS+= -DNDEBUG -I${LPRSRC} XSYM= host hrStorageOther hrStorageRam hrStorageVirtualMemory \ hrStorageFixedDisk hrStorageRemovableDisk hrStorageFloppyDisk \ hrStorageCompactDisc hrStorageRamDisk hrStorageFlashMemory \ @@ -60,8 +63,20 @@ hrFSHPFS hrFSHFS hrFSMFS hrFSNTFS hrFSVNode hrFSJournaled \ hrFSiso9660 hrFSRockRidge hrFSNFS hrFSNetware hrFSAFS hrFSDFS \ hrFSAppleshare hrFSRFS hrFSDGCFS hrFSBFS hrFSFAT32 hrFSLinuxExt2 - + +MAN= snmp_hostres.3 + DEFS= ${MOD}_tree.def -BMIBS= HOST-RESOURCES-MIB.txt HOST-RESOURCES-TYPES.txt -LDADD= -lkvm -ldevinfo -lm -ldisk -.include <bsd.lib.mk> +BMIBS= BEGEMOT-HOSTRES-MIB.txt + +DPADD= ${LIBKVM} ${LIBDEVINFO} ${LIBM} ${LIBGEOM} ${LIBMEMSTAT} +LDADD= -lkvm -ldevinfo -lm -lgeom -lmemstat + +.include <bsd.snmpmod.mk> + +printcap.So: printcap.c + ${CC} ${PICFLAG} -DPIC ${CFLAGS:C/^-W.*//} -c ${.IMPSRC} -o ${.TARGET} + +smilint: + env SMIPATH=.:/usr/share/snmp/mibs:/usr/local/share/snmp/mibs \ + smilint -c /dev/null -l6 -i group-membership BEGEMOT-HOSTRES-MIB ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c#13 (text+ko) ==== @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2005 The FreeBSD Project + /*- + * Copyright (c) 2005-2006 The FreeBSD Project * All rights reserved. * * Author: Victor Cruceru <soc-victor@freebsd.org> @@ -26,139 +26,173 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * + * $FreeBSD: src/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_device_tbl.c,v 1.2 2006/01/09 13:01:26 harti Exp $ + */ + +/* * Host Resources MIB: hrDeviceTable implementation for SNMPd. */ + +#include <sys/un.h> +#include <sys/limits.h> + +#include <assert.h> +#include <err.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + #include "hostres_snmp.h" #include "hostres_oid.h" #include "hostres_tree.h" -#include <syslog.h> -#include <string.h> -#include <assert.h> -#include <stdlib.h> -#include <err.h> -#include <sys/un.h> -#include <unistd.h> -#include <errno.h> + +/* + * Status of a device + */ +enum DeviceStatus { + DS_UNKNOWN = 1, + DS_RUNNING = 2, + DS_WARNING = 3, + DS_TESTING = 4, + DS_DOWN = 5 +}; + +TAILQ_HEAD(device_tbl, device_entry); + +/* the head of the list with hrDeviceTable's entries */ +static struct device_tbl device_tbl = TAILQ_HEAD_INITIALIZER(device_tbl); + +/* Table used for consistent device table indexing. */ +struct device_map device_map = STAILQ_HEAD_INITIALIZER(device_map); + +/* next int available for indexing the hrDeviceTable */ +static uint32_t next_device_index = 1; + +/* last (agent) tick when hrDeviceTable was updated */ +static uint64_t device_tick = 0; -/*some prototypes*/ -int hr_device_collector(struct devinfo_dev *dev, void *arg); +/* maximum number of ticks between updates of device table */ +uint32_t device_tbl_refresh = 10 * 100; -void -hrDeviceTblEntry_delete_v( struct hrDeviceTblEntry* entry ); +/* socket for /var/run/devd.pipe */ +static int devd_sock = -1; -struct hrDeviceTblEntry * -hrDeviceTblEntry_find_by_index(int32_t idx); +/* used to wait notifications from /var/run/devd.pipe */ +static void *devd_fd; -/*some constant variables*/ -static -const struct asn_oid OIDX_hrDeviceProcessor_c = OIDX_hrDeviceProcessor; +/* some constants */ +static const struct asn_oid OIDX_hrDeviceProcessor_c = OIDX_hrDeviceProcessor; +static const struct asn_oid OIDX_hrDeviceOther_c = OIDX_hrDeviceOther; -static -const struct asn_oid OIDX_hrDeviceOther_c = OIDX_hrDeviceOther; +/** + * Create a new entry out of thin air. + */ +struct device_entry * +device_entry_create(const char *name, const char *location, const char *descr) +{ + struct device_entry *entry; + struct device_map_entry *map; -static -struct hrDeviceTblEntry* -hrDeviceTblEntry_create( const struct devinfo_dev *dev_p) { - struct - hrDeviceTblEntry *entry; - struct - deviceNameMapEntry *map = NULL; + assert((name[0] != 0) || (location[0] != 0)); - - assert(dev_p->dd_name != NULL); - assert(dev_p->dd_location != NULL); - if (dev_p->dd_name == NULL && dev_p->dd_location == NULL) { + if (name[0] == 0 && location[0] == 0) return (NULL); - } - - assert((dev_p->dd_name[0] != 0) || (dev_p->dd_location[0] != 0)); - if (dev_p->dd_name[0] == 0 && dev_p->dd_location[0] == 0) { - return (NULL); - } - if ((entry = malloc(sizeof(*entry))) == NULL) { syslog(LOG_WARNING, "hrDeviceTable: %s: %m", __func__); return (NULL); } memset(entry, 0, sizeof(*entry)); - - STAILQ_FOREACH(map, &hrState_g.device_name_map, link) - if (strcmp((const char *)map->name_key, - (const char *)dev_p->dd_name) == 0 && - strcmp((const char *)map->location_key, - (const char *)dev_p->dd_location) == 0) { - + STAILQ_FOREACH(map, &device_map, link) + if (strcmp(map->name_key, name) == 0 && + strcmp(map->location_key, location) == 0) { entry->index = map->hrIndex; map->entry_p = entry; break; } - + if (map == NULL) { /* new object - get a new index */ - if (hrState_g.next_hrDevice_index > INT_MAX) { - syslog(LOG_ERR, "%s: hrDeviceTable index wrap", __func__ ); - errx(1, "hrDeviceTable index wrap"); - } + if (next_device_index > INT_MAX) { + syslog(LOG_ERR, + "%s: hrDeviceTable index wrap", __func__); + free(entry); + return (NULL); + } if ((map = malloc(sizeof(*map))) == NULL) { syslog(LOG_ERR, "hrDeviceTable: %s: %m", __func__ ); free(entry); return (NULL); } - map->hrIndex = hrState_g.next_hrDevice_index ++; - - memset(&map->name_key[0], 0, sizeof(map->name_key)); - - strncpy( (char*)map->name_key, - (const char *)dev_p->dd_name, - sizeof(map->name_key) - 1); - - memset(&map->location_key[0], 0, sizeof(map->location_key)); - strncpy((char*)map->location_key, - dev_p->dd_location, - sizeof(map->location_key) - 1); + + map->hrIndex = next_device_index++; + + strlcpy(map->name_key, name, sizeof(map->name_key)); + strlcpy(map->location_key, location, sizeof(map->location_key)); map->entry_p = entry; - STAILQ_INSERT_TAIL(&hrState_g.device_name_map, map, link); - HR_DPRINTF((stderr, "%s at %s added into hrDeviceMap at index=%d\n ", - dev_p->dd_name, - dev_p->dd_location, map->hrIndex)); + + STAILQ_INSERT_TAIL(&device_map, map, link); + HRDBG("%s at %s added into hrDeviceMap at index=%d", + name, location, map->hrIndex); } else { - HR_DPRINTF((stderr, "%s at %s exists in hrDeviceMap index=%d\n ", - dev_p->dd_name, - dev_p->dd_location, map->hrIndex)); + HRDBG("%s at %s exists in hrDeviceMap index=%d", + name, location, map->hrIndex); + } - } - entry->index = map->hrIndex; - memset(&entry->name[0], 0, sizeof(entry->name)); - strncpy((char*)entry->name, - dev_p->dd_name, - sizeof(entry->name) - 1); - - memset(&entry->location[0], 0, sizeof(entry->location)); - strncpy((char*)entry->location, - dev_p->dd_location, - sizeof(entry->location) - 1); - - INSERT_OBJECT_INT(entry, &hrState_g.hr_device_tbl); - - return entry; - + + strlcpy(entry->name, name, sizeof(entry->name)); + strlcpy(entry->location, location, sizeof(entry->location)); + + if (name[0] != '\0') + snprintf(entry->descr, sizeof(entry->descr), "%s: %s", + name, descr); + else + snprintf(entry->descr, sizeof(entry->descr), + "unknown at %s: %s", location, descr); + + entry->id = oid_zeroDotZero; /* unknown id - FIXME */ + entry->status = (u_int)DIS_ATTACHED; + entry->errors = 0; + entry->type = OIDX_hrDeviceOther_c; + + INSERT_OBJECT_INT(entry, &device_tbl); + + return (entry); } +/** + * Create a new entry into the device table. + */ +static struct device_entry * +device_entry_create_devinfo(const struct devinfo_dev *dev_p) +{ + + assert(dev_p->dd_name != NULL); + assert(dev_p->dd_location != NULL); + + return (device_entry_create(dev_p->dd_name, dev_p->dd_location, + dev_p->dd_desc)); +} -void -hrDeviceTblEntry_delete_v( struct hrDeviceTblEntry* entry ) { - struct deviceNameMapEntry *map; +/** + * Delete an entry from the device table. + */ +static void +device_entry_delete(struct device_entry *entry) +{ + struct device_map_entry *map; + assert(entry != NULL); - + + TAILQ_REMOVE(&device_tbl, entry, link); - - TAILQ_REMOVE(&hrState_g.hr_device_tbl, entry, link); - STAILQ_FOREACH(map, &hrState_g.device_name_map, link) + STAILQ_FOREACH(map, &device_map, link) if (map->entry_p == entry) { map->entry_p = NULL; break; @@ -166,381 +200,413 @@ free(entry); } -static -struct hrDeviceTblEntry* -hrDeviceTblEntry_find_by_dev(const struct devinfo_dev *dev_p) { - struct deviceNameMapEntry *map; +/** + * Find an entry given its name and location + */ +static struct device_entry * +device_find_by_dev(const struct devinfo_dev *dev_p) +{ + struct device_map_entry *map; + assert(dev_p != NULL); - - STAILQ_FOREACH(map, &hrState_g.device_name_map, link) - if (strcmp((const char*)map->name_key, - (const char*)dev_p->dd_name) == 0 && - strcmp((const char*)map->location_key, - (const char*)dev_p->dd_location) == 0) { - + STAILQ_FOREACH(map, &device_map, link) + if (strcmp(map->name_key, dev_p->dd_name) == 0 && + strcmp(map->location_key, dev_p->dd_location) == 0) return (map->entry_p); - } return (NULL); } +/** + * Find an entry given its index. + */ +struct device_entry * +device_find_by_index(int32_t idx) +{ + struct device_entry *entry; + + TAILQ_FOREACH(entry, &device_tbl, link) + if (entry->index == idx) + return (entry); + return (NULL); +} -struct hrDeviceTblEntry * -hrDeviceTblEntry_find_by_index(int32_t idx) { +/** + * Find an device entry given its name. + */ +struct device_entry * +device_find_by_name(const char *dev_name) +{ + struct device_map_entry *map; + + assert(dev_name != NULL); - struct hrDeviceTblEntry *entry; + STAILQ_FOREACH(map, &device_map, link) + if (strcmp(map->name_key, dev_name) == 0) + return (map->entry_p); - TAILQ_FOREACH(entry, &hrState_g.hr_device_tbl, link) - if (entry->index == idx) - return (entry); return (NULL); } -static -void hrDevice_getType_v(struct devinfo_dev *dev_p, struct asn_oid *out_type_p) { - +/** + * Find out the type of device. CPU only currently. + */ +static void +device_get_type(struct devinfo_dev *dev_p, struct asn_oid *out_type_p) +{ + assert(dev_p != NULL); assert(out_type_p != NULL); - if(dev_p == NULL) + + if (dev_p == NULL) return; - - if (strncmp(dev_p->dd_name, "cpu", strlen("cpu")) == 0 && + + if (strncmp(dev_p->dd_name, "cpu", strlen("cpu")) == 0 && strstr(dev_p->dd_location, ".CPU") != NULL) { *out_type_p = OIDX_hrDeviceProcessor_c; return; - } - - *out_type_p = OIDX_hrDeviceOther_c; /*FIX ME*/ + } } -static -enum DeviceStatus -hrDevice_getStatus(struct devinfo_dev *dev) { +/** + * Get the status of a device + */ +static enum DeviceStatus +device_get_status(struct devinfo_dev *dev) +{ + assert(dev != NULL); + switch (dev->dd_state) { - case DIS_ALIVE: /* probe succeeded */ - case DIS_NOTPRESENT: /* not probed or probe failed */ - return (DS_DOWN); - case DIS_ATTACHED: /* attach method called */ - case DIS_BUSY: /* device is open */ - return (DS_RUNNING); - default: - return (DS_UNKNOWN); + case DIS_ALIVE: /* probe succeeded */ + case DIS_NOTPRESENT: /* not probed or probe failed */ + return (DS_DOWN); + case DIS_ATTACHED: /* attach method called */ + case DIS_BUSY: /* device is open */ + return (DS_RUNNING); + default: + return (DS_UNKNOWN); } } -int -hr_device_collector(struct devinfo_dev *dev, void *arg) { - struct hrDeviceTblEntry *entry = NULL; - if (dev->dd_name[0] !='\0' || dev->dd_location[0] != '\0') { - HR_DPRINTF((stderr, " %s: ANALYZING dev %s at %s\n ", - __func__, - dev->dd_name, - dev->dd_location)); - - entry = hrDeviceTblEntry_find_by_dev(dev); - if (entry == NULL) { - entry = hrDeviceTblEntry_create(dev); - } - assert(entry != NULL); - if (entry != NULL) { +/** + * Get the info for the given device and then recursively process all + * child devices. + */ +static int +device_collector(struct devinfo_dev *dev, void *arg) +{ + struct device_entry *entry; + + HRDBG("%llu/%llu name='%s' desc='%s' drivername='%s' location='%s'", + (unsigned long long)dev->dd_handle, + (unsigned long long)dev->dd_parent, dev->dd_name, dev->dd_desc, + dev->dd_drivername, dev->dd_location); + + if (dev->dd_name[0] != '\0' || dev->dd_location[0] != '\0') { + HRDBG("ANALYZING dev %s at %s", + dev->dd_name, dev->dd_location); + + if ((entry = device_find_by_dev(dev)) != NULL) { + entry->flags |= HR_DEVICE_FOUND; + entry->status = (u_int)device_get_status(dev); + } else if ((entry = device_entry_create_devinfo(dev)) != NULL) { + device_get_type(dev, &entry->type); + entry->flags |= HR_DEVICE_FOUND; - - hrDevice_getType_v(dev,&entry->type); - - memset(entry->descr, 0, sizeof(entry->descr)); - if (dev->dd_name[0] != '\0') { - (void)snprintf((char*)entry->descr, - sizeof(entry->descr) - 1,"%s: %s", - dev->dd_name, dev->dd_desc); - } else { - (void)snprintf((char*)entry->descr, - sizeof(entry->descr) - 1,"unknown at %s", - dev->dd_location); - - } - - entry->id = oid_zeroDotZero; /*unknown id - FIX ME*/ - - entry->status = (u_int)hrDevice_getStatus(dev); - - entry->errors = 0; /*FIX ME*/ + entry->status = (u_int)device_get_status(dev); + } + } else { + HRDBG("SKIPPED unknown device at location '%s'", + dev->dd_location ); + } + + return (devinfo_foreach_device_child(dev, device_collector, arg)); +} + +/** + * Create the socket to the device daemon. + */ +static int +create_devd_socket(void) +{ + int d_sock; + struct sockaddr_un devd_addr; + + bzero(&devd_addr, sizeof(struct sockaddr_un)); + + if ((d_sock = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { + syslog(LOG_ERR, "Failed to create the socket for %s: %m", + PATH_DEVD_PIPE); + return (-1); + } + + devd_addr.sun_family = PF_LOCAL; + devd_addr.sun_len = sizeof(devd_addr); + strlcpy(devd_addr.sun_path, PATH_DEVD_PIPE, + sizeof(devd_addr.sun_path) - 1); + + if (connect(d_sock, (struct sockaddr *)&devd_addr, + sizeof(devd_addr)) == -1) { + syslog(LOG_ERR,"Failed to connect socket for %s: %m", + PATH_DEVD_PIPE); + if (close(d_sock) < 0 ) + syslog(LOG_ERR,"Failed to close socket for %s: %m", + PATH_DEVD_PIPE); + return (-1); + } + + return (d_sock); +} + +/* + * Event on the devd socket. + ** + * We should probably directly process entries here. For simplicity just + * call the refresh routine with the force flag for now. + */ +static void +devd_socket_callback(int fd, void *arg __unused) +{ + char buf[512]; + int read_len = -1; + + assert(fd == devd_sock); + + HRDBG("called"); + + read_len = read(fd, buf, sizeof(buf) - 1); + if (read_len < 0) { + if (errno == EBADF) { + devd_sock = -1; + if (devd_fd != NULL) { + fd_deselect(devd_fd); + devd_fd = NULL; + } + syslog(LOG_ERR, "Closing devd_fd, revert to " + "devinfo polling"); + } + + } else if (read_len == 0) { + syslog(LOG_ERR, "zero bytes read from devd pipe... " + "closing socket!"); + + if (close(devd_sock) < 0 ) + syslog(LOG_ERR, "Failed to close devd socket: %m"); + + devd_sock = -1; + if (devd_fd != NULL) { + fd_deselect(devd_fd); + devd_fd = NULL; } + syslog(LOG_ERR, "Closing devd_fd, revert to devinfo polling"); } else { - syslog(LOG_ERR, - "hrDeviceTable: SKIPPED unknown device at location %s", - dev->dd_location ); + switch (buf[0]) { + case '+': + case '-': + case '?': + refresh_device_tbl(1); + return; + default: + syslog(LOG_ERR, "unknown message from devd socket"); + } } - return(devinfo_foreach_device_child(dev, hr_device_collector, arg)); } -static -void hrDevice_OS_get_devices_v(void) { +/** + * Initialize and populate the device table. + */ +void +init_device_tbl(void) +{ + + /* initially populate table for the other tables */ + refresh_device_tbl(1); - if (hrState_g.dev_root == NULL) { - syslog(LOG_ERR, "hrDeviceTable: not inited? "); - return; - } - if (devinfo_foreach_device_child(hrState_g.dev_root, hr_device_collector, (void *)0)) { - syslog(LOG_ERR, "hrDeviceTable: devinfo_foreach_device_child failed "); - return; - } + /* no problem if that fails - just use polling mode */ + devd_sock = create_devd_socket(); } -void init_hrDevice_tbl_v(void) { - refresh_hrDevice_tbl_v(); - +/** + * Start devd(8) monitoring. + */ +void +start_device_tbl(struct lmodule *mod) +{ + + if (devd_sock > 0) { + devd_fd = fd_select(devd_sock, devd_socket_callback, NULL, mod); + if (devd_fd == NULL) + syslog(LOG_ERR, "fd_select failed on devd socket: %m"); + } } -/* +/** * Finalization routine for hrDeviceTable * It destroys the lists and frees any allocated heap memory */ -void fini_hrDevice_tbl_v(void) { - struct deviceNameMapEntry *n1, *n2; - devinfo_free(); - - n1 = STAILQ_FIRST(&hrState_g.device_name_map); - while (n1 != NULL) { - n2 = STAILQ_NEXT(n1, link); - if(n1->entry_p != NULL){ - TAILQ_REMOVE(&hrState_g.hr_device_tbl, n1->entry_p, link); - free( n1->entry_p ); - n1->entry_p = NULL; - } - free(n1); - n1 = n2; +void +fini_device_tbl(void) +{ + struct device_map_entry *n1; + + if (devd_fd != NULL) + fd_deselect(devd_fd); + + if (devd_sock != -1) + (void)close(devd_sock); + + devinfo_free(); + + while ((n1 = STAILQ_FIRST(&device_map)) != NULL) { + STAILQ_REMOVE_HEAD(&device_map, link); + if (n1->entry_p != NULL) { + TAILQ_REMOVE(&device_tbl, n1->entry_p, link); + free(n1->entry_p); + } + free(n1); } - STAILQ_INIT(&hrState_g.device_name_map); - + assert(TAILQ_EMPTY(&device_tbl)); } -/* - * Refresh routine for hrDeviceTable - * Usable for polling the system for any changes. +/** + * Refresh routine for hrDeviceTable. We don't refresh here if the devd socket + * is open, because in this case we have the actual information always. We + * also don't refresh when the table is new enough (if we don't have a devd + * socket). In either case a refresh can be forced by passing a non-zero value. */ -void refresh_hrDevice_tbl_v(void) { +void +refresh_device_tbl(int force) +{ + struct device_entry *entry, *entry_tmp; + struct devinfo_dev *dev_root; + static int act = 0; - struct hrDeviceTblEntry *entry = NULL, *entry_tmp = NULL; - - if ( hrState_g.devd_sock < 0 && this_tick <= hrState_g.hr_device_tick) { - HR_DPRINTF((stderr, "%s: no refresh needed\n ",__func__)); + if (!force && (devd_sock >= 0 || + (device_tick != 0 && this_tick - device_tick < device_tbl_refresh))){ + HRDBG("no refresh needed"); return; } - if ( hrState_g.dev_root != NULL ) { - syslog(LOG_ERR,"hrDeviceTable: attempt to re-initialization of devinfo."); + + if (act) { + syslog(LOG_ERR, "%s: recursive call", __func__); return; } + if (devinfo_init() != 0) { - syslog(LOG_ERR,"hrDeviceTable: devinfo_init failed: %m"); + syslog(LOG_ERR,"%s: devinfo_init failed: %m", __func__); return; - } - hrState_g.dev_root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE); - - if (hrState_g.dev_root == NULL) { - syslog(LOG_ERR,"hrDeviceTable: can't get the root device: %m. Most likely you need to upgrade libdevinfo!"); - return; + + act = 1; + if ((dev_root = devinfo_handle_to_device(DEVINFO_ROOT_DEVICE)) == NULL){ + syslog(LOG_ERR, "%s: can't get the root device: %m", __func__); + goto out; } - - /*mark each entry as missing*/ - TAILQ_FOREACH(entry, &hrState_g.hr_device_tbl, link) { + /* mark each entry as missing */ + TAILQ_FOREACH(entry, &device_tbl, link) entry->flags &= ~HR_DEVICE_FOUND; - } - - hrDevice_OS_get_devices_v(); + + if (devinfo_foreach_device_child(dev_root, device_collector, NULL)) + syslog(LOG_ERR, "%s: devinfo_foreach_device_child failed", + __func__); /* * Purge items that disappeared */ - entry = TAILQ_FIRST(&hrState_g.hr_device_tbl); - while (entry != NULL) { - entry_tmp = TAILQ_NEXT(entry, link); + TAILQ_FOREACH_SAFE(entry, &device_tbl, link, entry_tmp) { /* * If HR_DEVICE_IMMUTABLE bit is set then this means that - * this entry was not detected by the above hrDevice_OS_get_devices_v() - * call. So we are not deleting it there. + * this entry was not detected by the above + * devinfo_foreach_device() call. So we are not deleting + * it there. */ - if (!(entry->flags & HR_DEVICE_FOUND) && !(entry->flags & HR_DEVICE_IMMUTABLE) ) - hrDeviceTblEntry_delete_v(entry); - entry = entry_tmp; + if (!(entry->flags & HR_DEVICE_FOUND) && + !(entry->flags & HR_DEVICE_IMMUTABLE)) + device_entry_delete(entry); } - - hrState_g.hr_device_tick = this_tick; - - hrState_g.hrDevice_tbl_age = time(NULL); - - - devinfo_free(); - hrState_g.dev_root = NULL; + + device_tick = this_tick; /* - * Force a refresh for the hrDiskStorageTable - */ - refresh_DiskStorage_tbl_v(); - HR_DPRINTF((stderr, "%s: refresh DONE\n ",__func__)); + * Force a refresh for the hrDiskStorageTable + * XXX Why not the other dependen tables? + */ + refresh_disk_storage_tbl(1); + out: + devinfo_free(); + act = 0; } - -int create_devd_socket(void) { - static const char devd_pipe_name[]="/var/run/devd.pipe"; - int d_sock = -1; - struct sockaddr_un devd_addr; - - bzero(&devd_addr, sizeof(struct sockaddr_un)); - - if ((d_sock = socket(PF_LOCAL, SOCK_STREAM, 0)) < 0) { - syslog(LOG_ERR,"Failed to create the socket for %s: %m", devd_pipe_name); - return (-1); - } - - devd_addr.sun_family = PF_LOCAL; - - (void)strlcpy(devd_addr.sun_path, - devd_pipe_name, - sizeof(devd_addr.sun_path) - 1); - - if (connect(d_sock, (struct sockaddr *)&devd_addr, - sizeof(struct sockaddr_un)) == -1) { - syslog(LOG_ERR,"Failed to connect the socket for %s: %m", devd_pipe_name); - if (close(d_sock) < 0 ){ - syslog(LOG_ERR,"Failed to close the socket for %s: %m", devd_pipe_name); - } - return (-1); - } - - return d_sock; -} - -void devd_socket_callback(int fd , void* arg __unused) { - char buf[512]; - int read_len = -1; - assert(fd == hrState_g.devd_sock); - HR_DPRINTF((stderr, "__hrDeviceTable__ %s: called\n ", __func__)); - read_len = read(fd, buf, sizeof(buf) - 1); - if (read_len < 0) { - if(errno == EBADF){ - hrState_g.devd_sock = -1; - if (hrState_g.devd_fd != NULL) { - fd_deselect(hrState_g.devd_fd); - hrState_g.devd_fd = NULL; - } - syslog(LOG_ERR,"Closing devd_fd, revert to devinfo polling"); - } - - } else if (read_len == 0) { - syslog(LOG_ERR,"zero bytes read from devd pipe....closing socket! "); - if (close(hrState_g.devd_sock) < 0 ){ - syslog(LOG_ERR,"Failed to close the devd socket: %m"); - } - hrState_g.devd_sock = -1; - if (hrState_g.devd_fd != NULL) { - fd_deselect(hrState_g.devd_fd); - hrState_g.devd_fd = NULL; - } - syslog(LOG_ERR,"Closing devd_fd, revert to devinfo polling"); - - - } else { - switch(buf[0]){ - case '+': - case '-': - case '?': - refresh_hrDevice_tbl_v(); - return; - default: - syslog(LOG_ERR,"unknown message read from devd socket"); - - } - } -} - -/* - * This is the implementation for a generated (by a SNMP tool) - * function prototype, see hostres_tree.h +/** + * This is the implementation for a generated (by a SNMP tool) + * function prototype, see hostres_tree.h * It handles the SNMP operations for hrDeviceTable */ -int op_hrDeviceTable(struct snmp_context *ctx __unused, - struct snmp_value *value, - u_int sub, - u_int iidx __unused, - enum snmp_op curr_op ) +int +op_hrDeviceTable(struct snmp_context *ctx __unused, struct snmp_value *value, + u_int sub, u_int iidx __unused, enum snmp_op curr_op) { - struct hrDeviceTblEntry *entry = NULL; - int ret = SNMP_ERR_NOERROR; + struct device_entry *entry; + refresh_device_tbl(0); -/* - refresh entries here?! -*/ - if ( hrState_g.devd_sock < 0 && - (time(NULL) - hrState_g.hrDevice_tbl_age) > HR_DEVICE_TBL_REFRESH ) { - HR_DPRINTF((stderr, "__hrDeviceTable__ %s: need refresh\n ", __func__)); - refresh_hrDevice_tbl_v(); - } - - switch (curr_op) { >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200606031557.k53Fva0S048290>