Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 8 May 2013 20:03:38 +0000 (UTC)
From:      Mikolaj Golub <trociny@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r250379 - in head/usr.sbin/bsnmpd/modules: . snmp_hast
Message-ID:  <201305082003.r48K3cYv062256@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: trociny
Date: Wed May  8 20:03:37 2013
New Revision: 250379
URL: http://svnweb.freebsd.org/changeset/base/250379

Log:
  HAST module for bsnmpd(1).
  
  Reviewed by:	harti, pjd
  MFC after:	2 weeks

Added:
  head/usr.sbin/bsnmpd/modules/snmp_hast/
  head/usr.sbin/bsnmpd/modules/snmp_hast/BEGEMOT-HAST-MIB.txt   (contents, props changed)
  head/usr.sbin/bsnmpd/modules/snmp_hast/Makefile   (contents, props changed)
  head/usr.sbin/bsnmpd/modules/snmp_hast/hast_snmp.c   (contents, props changed)
  head/usr.sbin/bsnmpd/modules/snmp_hast/hast_tree.def   (contents, props changed)
  head/usr.sbin/bsnmpd/modules/snmp_hast/snmp_hast.8   (contents, props changed)
Modified:
  head/usr.sbin/bsnmpd/modules/Makefile

Modified: head/usr.sbin/bsnmpd/modules/Makefile
==============================================================================
--- head/usr.sbin/bsnmpd/modules/Makefile	Wed May  8 19:11:47 2013	(r250378)
+++ head/usr.sbin/bsnmpd/modules/Makefile	Wed May  8 20:03:37 2013	(r250379)
@@ -10,6 +10,7 @@ _snmp_atm= snmp_atm
 
 SUBDIR=	${_snmp_atm} \
 	snmp_bridge \
+	snmp_hast \
 	snmp_hostres \
 	snmp_mibII \
 	snmp_pf \

Added: head/usr.sbin/bsnmpd/modules/snmp_hast/BEGEMOT-HAST-MIB.txt
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bsnmpd/modules/snmp_hast/BEGEMOT-HAST-MIB.txt	Wed May  8 20:03:37 2013	(r250379)
@@ -0,0 +1,298 @@
+--
+-- Copyright (c) 2013 Mikolaj Golub <trociny@FreeBSD.org>
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions
+-- are met:
+-- 1. Redistributions of source code must retain the above copyright
+--    notice, this list of conditions and the following disclaimer.
+-- 2. Redistributions in binary form must reproduce the above copyright
+--    notice, this list of conditions and the following disclaimer in the
+--    documentation and/or other materials provided with the distribution.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+-- ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+-- SUCH DAMAGE.
+--
+-- $FreeBSD$
+--
+
+BEGEMOT-HAST-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE,
+    Counter64, Integer32
+	FROM SNMPv2-SMI
+    TEXTUAL-CONVENTION, RowStatus
+	FROM SNMPv2-TC
+    InterfaceIndex, ifIndex
+	FROM IF-MIB
+    begemot
+	FROM BEGEMOT-MIB;
+
+begemotHast MODULE-IDENTITY
+    LAST-UPDATED "201304130000Z"
+    ORGANIZATION "FreeBSD"
+    CONTACT-INFO
+	    "		Mikolaj Golub
+
+	     Postal:	Bluhera 27v 11
+			61146 Kharkiv
+			Ukraine
+
+	     Fax:	N/A
+
+	     E-Mail:	trociny@FreeBSD.org"
+    DESCRIPTION
+	    "The Begemot MIB for managing HAST."
+    REVISION     "201304130000Z"
+    DESCRIPTION
+	    "Initial revision."
+    ::= { begemot 220 }
+
+begemotHastObjects	OBJECT IDENTIFIER ::= { begemotHast 1 }
+
+-- ---------------------------------------------------------- --
+-- Configuration parameters
+-- ---------------------------------------------------------- --
+
+hastConfig	OBJECT IDENTIFIER ::= { begemotHastObjects 1 }
+
+hastConfigFile OBJECT-TYPE
+    SYNTAX	OCTET STRING
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	    "HAST configuration file location."
+    ::= { hastConfig 1 }
+
+-- ---------------------------------------------------------- --
+-- Resource Table
+-- ---------------------------------------------------------- --
+hastResourceTable OBJECT-TYPE
+    SYNTAX	SEQUENCE OF HastResourceEntry
+    MAX-ACCESS	not-accessible
+    STATUS	current
+    DESCRIPTION
+	"A table containing information about all HAST resources."
+    ::= { begemotHastObjects 2 }
+
+hastResourceEntry OBJECT-TYPE
+    SYNTAX	HastResourceEntry
+    MAX-ACCESS	not-accessible
+    STATUS	current
+    DESCRIPTION
+	"Table entry that describes one HAST resource."
+    INDEX	{ hastResourceIndex }
+    ::= { hastResourceTable 1 }
+
+HastResourceEntry ::= SEQUENCE {
+    hastResourceIndex			Integer32,
+    hastResourceName			OCTET STRING,
+    hastResourceRole			INTEGER,
+    hastResourceProvName		OCTET STRING,
+    hastResourceLocalPath		OCTET STRING,
+    hastResourceExtentSize		Integer32,
+    hastResourceKeepDirty		Integer32,
+    hastResourceRemoteAddr		OCTET STRING,
+    hastResourceSourceAddr		OCTET STRING,
+    hastResourceReplication		INTEGER,
+    hastResourceStatus			INTEGER,
+    hastResourceDirty			Counter64,
+    hastResourceReads			Counter64,
+    hastResourceWrites			Counter64,
+    hastResourceDeletes			Counter64,
+    hastResourceFlushes			Counter64,
+    hastResourceActivemapUpdates	Counter64,
+    hastResourceReadErrors		Counter64,
+    hastResourceWriteErrors		Counter64,
+    hastResourceDeleteErrors		Counter64,
+    hastResourceFlushErrors		Counter64
+}
+
+hastResourceIndex OBJECT-TYPE
+    SYNTAX	Integer32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Resource index."
+    ::= { hastResourceEntry 1 }
+
+hastResourceName OBJECT-TYPE
+    SYNTAX	OCTET STRING
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Resource name."
+    ::= { hastResourceEntry 2 }
+
+hastResourceRole OBJECT-TYPE
+    SYNTAX	INTEGER { undef(0), init(1), primary(2), secondary(3) }
+    MAX-ACCESS	read-write
+    STATUS	current
+    DESCRIPTION
+	"Resource role."
+    ::= { hastResourceEntry 3 }
+
+hastResourceProvName OBJECT-TYPE
+    SYNTAX	OCTET STRING
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Resource GEOM provider name that appears as /dev/hast/<name>."
+    ::= { hastResourceEntry 4 }
+
+hastResourceLocalPath OBJECT-TYPE
+    SYNTAX	OCTET STRING
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Path to the local component which is used as a backend
+	provider for the resource."
+    ::= { hastResourceEntry 5 }
+
+hastResourceExtentSize OBJECT-TYPE
+    SYNTAX	Integer32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Size of an extent.  Extent is a block which is
+	used for synchronization.  hastd(8) maintains a
+	map of dirty extents and extent is the smallest
+	region that can be marked as dirty.  If any part
+	of an extent is modified, entire extent will be
+	synchronized when nodes connect."
+    ::= { hastResourceEntry 6 }
+
+hastResourceKeepDirty OBJECT-TYPE
+    SYNTAX	Integer32
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Maximum number of dirty extents to keep dirty all
+	the time.  Most recently used extents are kept
+	dirty to reduce number of metadata updates."
+    ::= { hastResourceEntry 7 }
+
+hastResourceRemoteAddr OBJECT-TYPE
+    SYNTAX	OCTET STRING
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Address of the remote hastd(8) daemon for the resource."
+    ::= { hastResourceEntry 8 }
+
+hastResourceSourceAddr OBJECT-TYPE
+    SYNTAX	OCTET STRING
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Local address the resource is bound to."
+    ::= { hastResourceEntry 9 }
+
+hastResourceReplication OBJECT-TYPE
+    SYNTAX	INTEGER { fullsync(0), memsync(1), async(2) }
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Resource replication mode."
+    ::= { hastResourceEntry 10 }
+
+hastResourceStatus OBJECT-TYPE
+    SYNTAX	INTEGER { complete(0), degraded(1) }
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Resource replication status."
+    ::= { hastResourceEntry 11 }
+
+hastResourceDirty OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Current number of dirty extents for the resource."
+    ::= { hastResourceEntry 12 }
+
+hastResourceReads OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local read operations."
+    ::= { hastResourceEntry 13 }
+
+hastResourceWrites OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local write operations."
+    ::= { hastResourceEntry 14 }
+
+hastResourceDeletes OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local delete operations."
+    ::= { hastResourceEntry 15 }
+
+hastResourceFlushes OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local flush operations."
+    ::= { hastResourceEntry 16 }
+
+hastResourceActivemapUpdates OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local activemap updates."
+    ::= { hastResourceEntry 17 }
+
+hastResourceReadErrors OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local read operations that failed."
+    ::= { hastResourceEntry 18 }
+
+hastResourceWriteErrors OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local write operations that failed."
+    ::= { hastResourceEntry 19 }
+
+hastResourceDeleteErrors OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local delete operations that failed."
+    ::= { hastResourceEntry 20 }
+
+hastResourceFlushErrors OBJECT-TYPE
+    SYNTAX	Counter64
+    MAX-ACCESS	read-only
+    STATUS	current
+    DESCRIPTION
+	"Count of resource local flush operations that failed."
+    ::= { hastResourceEntry 21 }
+
+END

Added: head/usr.sbin/bsnmpd/modules/snmp_hast/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bsnmpd/modules/snmp_hast/Makefile	Wed May  8 20:03:37 2013	(r250379)
@@ -0,0 +1,43 @@
+# $FreeBSD$
+
+.include <bsd.own.mk>
+
+.PATH:	${.CURDIR}/../../../../sbin/hastd
+
+MOD=	hast
+SRCS=	ebuf.c
+SRCS+=	hast_compression.c hast_proto.c hast_snmp.c
+SRCS+=	lzf.c
+SRCS+=	nv.c
+SRCS+=	parse.y pjdlog.c
+SRCS+=	proto.c proto_common.c proto_uds.c
+SRCS+=	token.l
+SRCS+=	y.tab.h
+MAN=	snmp_hast.8
+
+NO_WFORMAT=
+NO_WCAST_ALIGN=
+NO_WMISSING_VARIABLE_DECLARATIONS=
+CFLAGS+=-I${.CURDIR}/../../../../sbin/hastd
+CFLAGS+=-DHAVE_CAPSICUM
+CFLAGS+=-DINET
+.if ${MK_INET6_SUPPORT} != "no"
+CFLAGS+=-DINET6
+.endif
+# This is needed to have WARNS > 1.
+CFLAGS+=-DYY_NO_UNPUT
+CFLAGS+=-DYY_NO_INPUT
+CFLAGS+= -DSNMPTREE_TYPES
+
+DPADD=	${LIBL} ${LIBUTIL}
+LDADD=	-ll -lutil
+
+XSYM=	begemotHast
+DEFS=	${MOD}_tree.def
+BMIBS=	BEGEMOT-HAST-MIB.txt
+
+YFLAGS+=-v
+
+CLEANFILES=y.tab.c y.tab.h y.output
+
+.include <bsd.snmpmod.mk>

Added: head/usr.sbin/bsnmpd/modules/snmp_hast/hast_snmp.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bsnmpd/modules/snmp_hast/hast_snmp.c	Wed May  8 20:03:37 2013	(r250379)
@@ -0,0 +1,506 @@
+/*-
+ * Copyright (c) 2013 Mikolaj Golub <trociny@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/queue.h>
+
+#include <bsnmp/snmpmod.h>
+
+#include <string.h>
+
+#include "hast.h"
+#include "hast_oid.h"
+#include "hast_proto.h"
+#include "hast_tree.h"
+#include "nv.h"
+#include "pjdlog.h"
+#include "proto.h"
+
+#define UPDATE_INTERVAL	500	/* update interval in ticks */
+
+static struct lmodule *module;
+
+static const struct asn_oid oid_hast = OIDX_begemotHast;
+
+/* the Object Resource registration index */
+static u_int hast_index = 0;
+
+/*
+ * Structure that describes single resource.
+ */
+struct hast_snmp_resource {
+	TAILQ_ENTRY(hast_snmp_resource) link;
+	int32_t		index;
+	char		name[NAME_MAX];
+	int		error;
+	int		role;
+	char		provname[NAME_MAX];
+	char		localpath[PATH_MAX];
+	int32_t		extentsize;
+	int32_t		keepdirty;
+	char		remoteaddr[HAST_ADDRSIZE];
+	char		sourceaddr[HAST_ADDRSIZE];
+	int		replication;
+	int		status;
+	uint64_t	dirty;
+	uint64_t	reads;
+	uint64_t	writes;
+	uint64_t	deletes;
+	uint64_t	flushes;
+	uint64_t	activemap_updates;
+	uint64_t	read_errors;
+	uint64_t	write_errors;
+	uint64_t	delete_errors;
+	uint64_t	flush_errors;
+};
+
+static TAILQ_HEAD(, hast_snmp_resource) resources =
+    TAILQ_HEAD_INITIALIZER(resources);
+
+/* Path to configuration file. */
+static u_char *cfgpath;
+/* Ticks of the last hast resources update. */
+static uint64_t last_resources_update;
+
+static void free_resources(void);
+static int hastctl(struct nv *nvin, struct nv **nvout);
+static int hast_fini(void);
+static int hast_init(struct lmodule *mod, int argc, char *argv[]);
+static void hast_start(void);
+static int set_role(const char *resource, int role);
+static int str2role(const char *str);
+static int str2replication(const char *str);
+static int str2status(const char *str);
+static int update_resources(void);
+
+const struct snmp_module config = {
+    .comment   = "This module implements the BEGEMOT MIB for HAST.",
+    .init      = hast_init,
+    .start     = hast_start,
+    .fini      = hast_fini,
+    .tree      = hast_ctree,
+    .tree_size = hast_CTREE_SIZE,
+};
+
+static int
+hast_init(struct lmodule *mod, int argc __unused, char *argv[] __unused)
+{
+
+	module = mod;
+
+	pjdlog_init(PJDLOG_MODE_SYSLOG);
+	pjdlog_debug_set(0);
+
+	cfgpath = malloc(sizeof(HAST_CONFIG));
+	if (cfgpath == NULL) {
+		pjdlog_error("Unable to allocate %zu bytes for cfgpath",
+		    sizeof(HAST_CONFIG));
+		return (-1);
+	}
+	strcpy(cfgpath, HAST_CONFIG);
+	return(0);
+}
+
+static void
+hast_start(void)
+{
+	hast_index = or_register(&oid_hast,
+	    "The MIB module for BEGEMOT-HAST-MIB.", module);
+}
+
+static int
+hast_fini(void)
+{
+
+	or_unregister(hast_index);
+	free_resources();
+	free(cfgpath);
+	return (0);
+}
+
+static void
+free_resources(void)
+{
+	struct hast_snmp_resource *res;
+
+	while ((res = TAILQ_FIRST(&resources)) != NULL) {
+		TAILQ_REMOVE(&resources, res, link);
+		free(res);
+	}
+}
+
+static int
+str2role(const char *str)
+{
+
+	if (strcmp(str, "init") == 0)
+		return (HAST_ROLE_INIT);
+	if (strcmp(str, "primary") == 0)
+		return (HAST_ROLE_PRIMARY);
+	if (strcmp(str, "secondary") == 0)
+		return (HAST_ROLE_SECONDARY);
+	return (HAST_ROLE_UNDEF);
+}
+
+static int
+str2replication(const char *str)
+{
+
+	if (strcmp(str, "fullsync") == 0)
+		return (HAST_REPLICATION_FULLSYNC);
+	if (strcmp(str, "memsync") == 0)
+		return (HAST_REPLICATION_MEMSYNC);
+	if (strcmp(str, "async") == 0)
+		return (HAST_REPLICATION_ASYNC);
+	return (-1);
+}
+
+static int
+str2status(const char *str)
+{
+
+	if (strcmp(str, "complete") == 0)
+		return (0);
+	if (strcmp(str, "degraded") == 0)
+		return (1);
+	return (-1);
+}
+
+static int
+hastctl(struct nv *nvin, struct nv **nvout)
+{
+	struct hastd_config *cfg;
+	struct proto_conn *conn;
+	struct nv *nv;
+	int error;
+
+	cfg = yy_config_parse(cfgpath, true);
+	if (cfg == NULL)
+		return (-1);
+
+	/* Setup control connection... */
+	if (proto_client(NULL, cfg->hc_controladdr, &conn) == -1) {
+		pjdlog_error("Unable to setup control connection to %s",
+		    cfg->hc_controladdr);
+		return (-1);
+	}
+	/* ...and connect to hastd. */
+	if (proto_connect(conn, HAST_TIMEOUT) == -1) {
+		pjdlog_error("Unable to connect to hastd via %s",
+		    cfg->hc_controladdr);
+		proto_close(conn);
+		return (-1);
+	}
+	/* Send the command to the server... */
+	if (hast_proto_send(NULL, conn, nvin, NULL, 0) == -1) {
+		pjdlog_error("Unable to send command to hastd via %s",
+		    cfg->hc_controladdr);
+		proto_close(conn);
+		return (-1);
+	}
+	/* ...and receive reply. */
+	if (hast_proto_recv_hdr(conn, &nv) == -1) {
+		pjdlog_error("cannot receive reply from hastd via %s",
+		    cfg->hc_controladdr);
+		proto_close(conn);
+		return (-1);
+	}
+	proto_close(conn);
+	error = nv_get_int16(nv, "error");
+	if (error != 0) {
+		pjdlog_error("Error %d received from hastd.", error);
+		nv_free(nv);
+		return (-1);
+	}
+	nv_set_error(nv, 0);
+	*nvout = nv;
+	return (0);
+}
+
+static int
+set_role(const char *resource, int role)
+{
+	struct nv *nvin, *nvout;
+	int error;
+
+	nvin = nv_alloc();
+	nv_add_string(nvin, resource, "resource%d", 0);
+	nv_add_uint8(nvin, HASTCTL_CMD_SETROLE, "cmd");
+	nv_add_uint8(nvin, role, "role");
+	error = hastctl(nvin, &nvout);
+	nv_free(nvin);
+	if (error != 0)
+		return (-1);
+	nv_free(nvout);
+	return (SNMP_ERR_NOERROR);
+}
+
+static int
+update_resources(void)
+{
+	struct hast_snmp_resource *res;
+	struct nv *nvin, *nvout;
+	static uint64_t now;
+	unsigned int i;
+	const char *str;
+	int error;
+
+	now = get_ticks();
+	if (now - last_resources_update < UPDATE_INTERVAL)
+		return (0);
+
+	last_resources_update = now;
+
+	free_resources();
+
+	nvin = nv_alloc();
+	nv_add_uint8(nvin, HASTCTL_CMD_STATUS, "cmd");
+	nv_add_string(nvin, "all", "resource%d", 0);
+	error = hastctl(nvin, &nvout);
+	nv_free(nvin);
+	if (error != 0)
+		return (-1);
+
+	for (i = 0; ; i++) {
+		str = nv_get_string(nvout, "resource%u", i);
+		if (str == NULL)
+			break;
+		res = calloc(1, sizeof(*res));
+		if (res == NULL) {
+			pjdlog_error("Unable to allocate %zu bytes for "
+			    "resource", sizeof(*res));
+			return (-1);
+		}
+		res->index = i + 1;
+		strncpy(res->name, str, sizeof(res->name) - 1);
+		error = nv_get_int16(nvout, "error%u", i);
+		if (error != 0)
+			continue;
+		str = nv_get_string(nvout, "role%u", i);
+		res->role = str != NULL ? str2role(str) : HAST_ROLE_UNDEF;
+		str = nv_get_string(nvout, "provname%u", i);
+		if (str != NULL)
+			strncpy(res->provname, str, sizeof(res->provname) - 1);
+		str = nv_get_string(nvout, "localpath%u", i);
+		if (str != NULL) {
+			strncpy(res->localpath, str,
+			    sizeof(res->localpath) - 1);
+		}
+		res->extentsize = nv_get_uint32(nvout, "extentsize%u", i);
+		res->keepdirty = nv_get_uint32(nvout, "keepdirty%u", i);
+		str = nv_get_string(nvout, "remoteaddr%u", i);
+		if (str != NULL) {
+			strncpy(res->remoteaddr, str,
+			    sizeof(res->remoteaddr) - 1);
+		}
+		str = nv_get_string(nvout, "sourceaddr%u", i);
+		if (str != NULL) {
+			strncpy(res->sourceaddr, str,
+			    sizeof(res->sourceaddr) - 1);
+		}
+		str = nv_get_string(nvout, "replication%u", i);
+		res->replication = str != NULL ? str2replication(str) : -1;
+		str = nv_get_string(nvout, "status%u", i);
+		res->status = str != NULL ? str2status(str) : -1;
+		res->dirty = nv_get_uint64(nvout, "dirty%u", i);
+		res->reads = nv_get_uint64(nvout, "stat_read%u", i);
+		res->writes = nv_get_uint64(nvout, "stat_write%u", i);
+		res->deletes = nv_get_uint64(nvout, "stat_delete%u", i);
+		res->flushes = nv_get_uint64(nvout, "stat_flush%u", i);
+		res->activemap_updates =
+		    nv_get_uint64(nvout, "stat_activemap_update%u", i);
+		res->read_errors =
+		    nv_get_uint64(nvout, "stat_read_error%u", i);
+		res->write_errors =
+		    nv_get_uint64(nvout, "stat_write_error%u", i);
+		res->delete_errors =
+		    nv_get_uint64(nvout, "stat_delete_error%u", i);
+		res->flush_errors =
+		    nv_get_uint64(nvout, "stat_flush_error%u", i);
+		TAILQ_INSERT_TAIL(&resources, res, link);
+	}
+	nv_free(nvout);
+	return (0);
+}
+
+int
+op_hastConfig(struct snmp_context *context, struct snmp_value *value,
+    u_int sub, u_int iidx __unused, enum snmp_op op)
+{
+	asn_subid_t which;
+
+	which = value->var.subs[sub - 1];
+
+	switch (op) {
+	case SNMP_OP_GET:
+		switch (which) {
+		case LEAF_hastConfigFile:
+			return (string_get(value, cfgpath, -1));
+		default:
+			return (SNMP_ERR_RES_UNAVAIL);
+		}
+	case SNMP_OP_SET:
+		switch (which) {
+		case LEAF_hastConfigFile:
+			return (string_save(value, context, -1,
+			    (u_char **)&cfgpath));
+		default:
+			return (SNMP_ERR_RES_UNAVAIL);
+		}
+	case SNMP_OP_GETNEXT:
+	case SNMP_OP_ROLLBACK:
+	case SNMP_OP_COMMIT:
+		return (SNMP_ERR_NOERROR);
+	default:
+		return (SNMP_ERR_RES_UNAVAIL);
+	}
+}
+
+int
+op_hastResourceTable(struct snmp_context *context __unused,
+    struct snmp_value *value, u_int sub, u_int iidx __unused, enum snmp_op op)
+{
+	struct hast_snmp_resource *res;
+	asn_subid_t which;
+	int ret;
+
+	if (update_resources() == -1)
+		return (SNMP_ERR_RES_UNAVAIL);
+
+	which = value->var.subs[sub - 1];
+
+	switch (op) {
+	case SNMP_OP_GETNEXT:
+		res = NEXT_OBJECT_INT(&resources, &value->var, sub);
+		if (res == NULL)
+			return (SNMP_ERR_NOSUCHNAME);
+		value->var.len = sub + 1;
+		value->var.subs[sub] = res->index;
+		break;
+	case SNMP_OP_GET:
+		if (value->var.len - sub != 1)
+			return (SNMP_ERR_NOSUCHNAME);
+		res = FIND_OBJECT_INT(&resources, &value->var, sub);
+		if (res == NULL)
+			return (SNMP_ERR_NOSUCHNAME);
+		break;
+	case SNMP_OP_SET:
+		res = FIND_OBJECT_INT(&resources, &value->var, sub);
+		if (res == NULL)
+			return (SNMP_ERR_NOSUCHNAME);
+		switch (which) {
+		case LEAF_hastResourceRole:
+			ret = set_role(res->name, value->v.integer);
+			/* force update on next run */
+			last_resources_update = 0;
+			break;
+		default:
+			ret = SNMP_ERR_NOT_WRITEABLE;
+			break;
+		}
+		return ret;
+	case SNMP_OP_ROLLBACK:
+	case SNMP_OP_COMMIT:
+		return (SNMP_ERR_NOERROR);
+	default:
+		return (SNMP_ERR_RES_UNAVAIL);
+	}
+
+	ret = SNMP_ERR_NOERROR;
+
+	switch (which) {
+	case LEAF_hastResourceIndex:
+		value->v.integer = res->index;
+		break;
+	case LEAF_hastResourceName:
+		ret = string_get(value, res->name, -1);
+		break;
+	case LEAF_hastResourceRole:
+		value->v.integer = res->role;
+		break;
+	case LEAF_hastResourceProvName:
+		ret = string_get(value, res->provname, -1);
+		break;
+	case LEAF_hastResourceLocalPath:
+		ret = string_get(value, res->localpath, -1);
+		break;
+	case LEAF_hastResourceExtentSize:
+		value->v.integer = res->extentsize;
+		break;
+	case LEAF_hastResourceKeepDirty:
+		value->v.integer = res->keepdirty;
+		break;
+	case LEAF_hastResourceRemoteAddr:
+		ret = string_get(value, res->remoteaddr, -1);
+		break;
+	case LEAF_hastResourceSourceAddr:
+		ret = string_get(value, res->sourceaddr, -1);
+		break;
+	case LEAF_hastResourceReplication:
+		value->v.integer = res->replication;
+		break;
+	case LEAF_hastResourceStatus:
+		value->v.integer = res->status;
+		break;
+	case LEAF_hastResourceDirty:
+		value->v.counter64 = res->dirty;
+		break;
+	case LEAF_hastResourceReads:
+		value->v.counter64 = res->reads;
+		break;
+	case LEAF_hastResourceWrites:
+		value->v.counter64 = res->writes;
+		break;
+	case LEAF_hastResourceDeletes:
+		value->v.counter64 = res->deletes;
+		break;
+	case LEAF_hastResourceFlushes:
+		value->v.counter64 = res->flushes;
+		break;
+	case LEAF_hastResourceActivemapUpdates:
+		value->v.counter64 = res->activemap_updates;
+		break;
+	case LEAF_hastResourceReadErrors:
+		value->v.counter64 = res->read_errors;
+		break;
+	case LEAF_hastResourceWriteErrors:
+		value->v.counter64 = res->write_errors;
+		break;
+	case LEAF_hastResourceDeleteErrors:
+		value->v.counter64 = res->delete_errors;
+		break;
+	case LEAF_hastResourceFlushErrors:
+		value->v.counter64 = res->flush_errors;
+		break;
+	default:
+		ret = SNMP_ERR_RES_UNAVAIL;
+		break;
+	}
+	return (ret);
+}

Added: head/usr.sbin/bsnmpd/modules/snmp_hast/hast_tree.def
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bsnmpd/modules/snmp_hast/hast_tree.def	Wed May  8 20:03:37 2013	(r250379)
@@ -0,0 +1,70 @@
+#-
+# Copyright (c) 2013 Mikolaj Golub <trociny@FreeBSD.org>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+(1 internet
+  (4 private
+    (1 enterprises
+      (12325 fokus
+        (1 begemot
+          (220 begemotHast
+            (1 begemotHastObjects
+              (1 hastConfig
+                (1 hastConfigFile OCTETSTRING op_hastConfig GET)
+              )
+              (2 hastResourceTable
+                (1 hastResourceEntry : OCTETSTRING op_hastResourceTable
+                  (1 hastResourceIndex INTEGER32 GET)
+                  (2 hastResourceName OCTETSTRING GET)
+                  (3 hastResourceRole INTEGER GET SET)
+                  (4 hastResourceProvName OCTETSTRING GET)
+                  (5 hastResourceLocalPath OCTETSTRING GET)
+                  (6 hastResourceExtentSize INTEGER32 GET)
+                  (7 hastResourceKeepDirty INTEGER32 GET)
+                  (8 hastResourceRemoteAddr OCTETSTRING GET)
+                  (9 hastResourceSourceAddr OCTETSTRING GET)
+                  (10 hastResourceReplication INTEGER GET)
+                  (11 hastResourceStatus INTEGER GET)
+                  (12 hastResourceDirty COUNTER64 GET)
+                  (13 hastResourceReads COUNTER64 GET)
+                  (14 hastResourceWrites COUNTER64 GET)
+                  (15 hastResourceDeletes COUNTER64 GET)
+                  (16 hastResourceFlushes COUNTER64 GET)
+                  (17 hastResourceActivemapUpdates COUNTER64 GET)
+                  (18 hastResourceReadErrors COUNTER64 GET)
+                  (19 hastResourceWriteErrors COUNTER64 GET)
+                  (20 hastResourceDeleteErrors COUNTER64 GET)
+                  (21 hastResourceFlushErrors COUNTER64 GET)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)

Added: head/usr.sbin/bsnmpd/modules/snmp_hast/snmp_hast.8
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/usr.sbin/bsnmpd/modules/snmp_hast/snmp_hast.8	Wed May  8 20:03:37 2013	(r250379)
@@ -0,0 +1,69 @@
+.\"-
+.\" Copyright (c) 2013 Mikolaj Golub <trociny@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd May 1, 2013
+.Dt SNMP_HAST 8
+.Os
+.Sh NAME
+.Nm snmp_hast
+.Nd "HAST module for"
+.Xr bsnmpd 1
+.Sh LIBRARY
+.Pq begemotSnmpdModulePath."hast" = "/usr/lib/snmp_hast.so"
+.Sh DESCRIPTION
+The
+.Nm snmp_hast
+module implements a private BEGEMOT-HAST-MIB, which allows
+management of HAST resources.
+.Pp
+The module uses
+.Xr hastd 8
+control socket to communicate with the daemon.
+.Va hastConfigFile
+variable can be used to specify the location of
+.Xr hast.conf 5
+file to find the address of the control connection.
+.Sh FILES
+.Bl -tag -width "XXXXXXXXX"
+.It Pa /usr/share/snmp/defs/hast_tree.def
+The description of the MIB tree implemented by
+.Nm .
+.It Pa /usr/share/snmp/mibs/BEGEMOT-HAST-MIB.txt
+The private BEGEMOT-HAST-MIB that is implemented by this module.
+.It Pa /etc/hast.conf
+The default

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305082003.r48K3cYv062256>