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