PERFORCE change 98397 for review
Shteryana Shopova
shteryana at FreeBSD.org
Sat Jun 3 15:59:13 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=98397
Change 98397 by shteryana at 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 at 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 at 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) <<<
More information about the p4-projects
mailing list