summaryrefslogtreecommitdiffstats
path: root/usr.sbin
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2006-01-26 10:13:32 +0000
committerharti <harti@FreeBSD.org>2006-01-26 10:13:32 +0000
commit14696be4fbd5832fdfbe82c55cff29dd987a6f36 (patch)
tree045d64291efeec49f1aba837122fb3d42e75ac95 /usr.sbin
parent4a6aaf32be14322abb6530ccbcfb8e3436778c3d (diff)
downloadFreeBSD-src-14696be4fbd5832fdfbe82c55cff29dd987a6f36.zip
FreeBSD-src-14696be4fbd5832fdfbe82c55cff29dd987a6f36.tar.gz
Fix the MIB to use libgeom instead of libdisk.
Submitted by: Victor Cruceru <soc-victor>
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/Makefile6
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c5
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c207
3 files changed, 170 insertions, 48 deletions
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile
index 475ad99..2922f45 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile
@@ -48,7 +48,7 @@ SRCS= hostres_begemot.c \
printcap.c
#Not having NDEBUG defined will enable assertions and a lot of output on stderr
-CFLAGS+= -DNDEBUG -I${LPRSRC}
+CFLAGS+= -DNDEBUG -I${LPRSRC}
XSYM= host hrStorageOther hrStorageRam hrStorageVirtualMemory \
hrStorageFixedDisk hrStorageRemovableDisk hrStorageFloppyDisk \
hrStorageCompactDisc hrStorageRamDisk hrStorageFlashMemory \
@@ -69,8 +69,8 @@ MAN= snmp_hostres.3
DEFS= ${MOD}_tree.def
BMIBS= BEGEMOT-HOSTRES-MIB.txt
-DPADD= ${LIBKVM} ${LIBDEVINFO} ${LIBM} ${LIBDISK} ${LIBMEMSTAT}
-LDADD= -lkvm -ldevinfo -lm -ldisk -lmemstat
+DPADD= ${LIBKVM} ${LIBDEVINFO} ${LIBM} ${LIBGEOM} ${LIBMEMSTAT}
+LDADD= -lkvm -ldevinfo -lm -lgeom -lmemstat
.include <bsd.snmpmod.mk>
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c
index e3d33a0..42f78cb 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_diskstorage_tbl.c
@@ -225,11 +225,8 @@ disk_query_disk(struct disk_entry *entry)
mediasize = mediasize / 1024;
entry->capacity = (mediasize > INT_MAX ? INT_MAX : mediasize);
+ partition_tbl_handle_disk(entry->index, entry->dev_name);
- if (entry->media == DSM_HARDDISK) {
- /* XXX libdisk crashes if a empty cdrom device is opened */
- partition_tbl_handle_disk(entry->index, entry->dev_name);
- }
(void)close(fd);
}
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c
index d6e55c0..f56513b 100644
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c
+++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c
@@ -38,7 +38,8 @@
#include <assert.h>
#include <err.h>
-#include <libdisk.h>
+#include <inttypes.h>
+#include <libgeom.h>
#include <paths.h>
#include <stdlib.h>
#include <string.h>
@@ -48,6 +49,12 @@
#include "hostres_oid.h"
#include "hostres_tree.h"
+#ifdef PC98
+#define HR_FREEBSD_PART_TYPE 0xc494
+#else
+#define HR_FREEBSD_PART_TYPE 165
+#endif
+
/*
* One row in the hrPartitionTable
*/
@@ -95,15 +102,14 @@ static uint32_t next_partition_index = 1;
* Create a new partition table entry
*/
static struct partition_entry *
-partition_entry_create(int32_t ds_index, const struct chunk *chunk)
+partition_entry_create(int32_t ds_index, const char *chunk_name)
{
struct partition_entry *entry;
struct partition_map_entry *map = NULL;
/* sanity checks */
- assert(chunk != NULL);
- assert(chunk->name != NULL);
- if (chunk == NULL || chunk->name == NULL || chunk->name[0] == '\0')
+ assert(chunk_name != NULL);
+ if (chunk_name == NULL || chunk_name[0] == '\0')
return (NULL);
if ((entry = malloc(sizeof(*entry))) == NULL) {
@@ -114,7 +120,7 @@ partition_entry_create(int32_t ds_index, const struct chunk *chunk)
/* check whether we already have seen this partition */
STAILQ_FOREACH(map, &partition_map, link)
- if (strcmp(map->id, chunk->name) == 0 ) {
+ if (strcmp(map->id, chunk_name) == 0 ) {
map->entry = entry;
break;
}
@@ -135,18 +141,17 @@ partition_entry_create(int32_t ds_index, const struct chunk *chunk)
map->index = next_partition_index++;
- memset(map->id, 0, sizeof(map->id));
- strncpy(map->id, chunk->name, sizeof(map->id) - 1);
+ strlcpy(map->id, chunk_name, sizeof(map->id));
map->entry = entry;
STAILQ_INSERT_TAIL(&partition_map, map, link);
HRDBG("%s added into hrPartitionMap at index=%d",
- chunk->name, map->index);
+ chunk_name, map->index);
} else {
HRDBG("%s exists in hrPartitionMap index=%d",
- chunk->name, map->index);
+ chunk_name, map->index);
}
/* create the index */
@@ -154,11 +159,10 @@ partition_entry_create(int32_t ds_index, const struct chunk *chunk)
entry->index.subs[0] = ds_index;
entry->index.subs[1] = map->index;
- memset(&entry->id[0], 0, sizeof(entry->id));
- strncpy(entry->id, chunk->name, sizeof(entry->id) - 1);
+ strlcpy(entry->id, chunk_name, sizeof(entry->id));
snprintf(entry->label, sizeof(entry->label) - 1,
- "%s%s", _PATH_DEV, chunk->name);
+ "%s%s", _PATH_DEV, chunk_name);
INSERT_OBJECT_OID(entry, &partition_tbl);
@@ -216,36 +220,33 @@ partition_entry_find_by_label(const char *name)
}
/**
- * Process a chunk from libdisk. A chunk is either a slice or a partition.
+ * Process a chunk from libgeom(4). A chunk is either a slice or a partition.
* If necessary create a new partition table entry for it. In any case
* set the size field of the entry and set the FOUND flag.
*/
static void
-handle_chunk(int32_t ds_index, const struct chunk* chunk,
- const struct disk *disk)
+handle_chunk(int32_t ds_index, const char *chunk_name, off_t chunk_size)
{
struct partition_entry *entry = NULL;
daddr_t k_size;
- assert(chunk != NULL);
- if (chunk == NULL)
+ assert(chunk_name != NULL);
+ assert(chunk_name[0] != '\0');
+ if (chunk_name == NULL || chunk_name == '\0')
return;
- if (chunk->type == unused) {
- HRDBG("SKIP unused chunk %s", chunk->name);
- return;
- }
- HRDBG("ANALYZE chunk %s", chunk->name);
+ HRDBG("ANALYZE chunk %s", chunk_name);
- if ((entry = partition_entry_find_by_name(chunk->name)) == NULL)
- if ((entry = partition_entry_create(ds_index, chunk)) == NULL)
+ if ((entry = partition_entry_find_by_name(chunk_name)) == NULL)
+ if ((entry = partition_entry_create(ds_index,
+ chunk_name)) == NULL)
return;
entry->flags |= HR_PARTITION_FOUND;
/* actual size may overflow the SNMP type */
- k_size = chunk->size / (1024 / disk->sector_size);
- entry->size = (k_size > (daddr_t)INT_MAX ? INT_MAX : k_size);
+ k_size = chunk_size / 1024;
+ entry->size = (k_size > (off_t)INT_MAX ? INT_MAX : k_size);
}
/**
@@ -264,31 +265,155 @@ partition_tbl_pre_refresh(void)
}
/**
- * Called from the DiskStorage table for every row. Open the device and
- * process all the partitions in it. ds_index is the index into the DiskStorage
- * table.
+ * Try to find a geom(4) class by its name. Returns a pointer to that
+ * class if found NULL otherways.
+ */
+static struct gclass *
+find_class(struct gmesh *mesh, const char *name)
+{
+ struct gclass *classp;
+
+ LIST_FOREACH(classp, &mesh->lg_class, lg_class)
+ if (strcmp(classp->lg_name, name) == 0)
+ return (classp);
+ return (NULL);
+}
+
+/**
+ * Process all MBR-type partitions from the given disk.
+ */
+static void
+get_mbr(struct gclass *classp, int32_t ds_index, const char *disk_dev_name)
+{
+ struct ggeom *gp;
+ struct gprovider *pp;
+ struct gconfig *conf;
+ long part_type;
+
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
+ /* We are only interested in partitions from this disk */
+ if (strcmp(gp->lg_name, disk_dev_name) != 0)
+ continue;
+
+ /*
+ * Find all the non-BSD providers (these are handled in get_bsd)
+ */
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ LIST_FOREACH(conf, &pp->lg_config, lg_config) {
+ if (conf->lg_name == NULL ||
+ conf->lg_val == NULL ||
+ strcmp(conf->lg_name, "type") != 0)
+ continue;
+
+ /*
+ * We are not interested in BSD partitions
+ * (ie ad0s1 is not interesting at this point).
+ * We'll take care of them in detail (slice
+ * by slice) in get_bsd.
+ */
+ part_type = strtol(conf->lg_val, NULL, 10);
+ if (part_type == HR_FREEBSD_PART_TYPE)
+ break;
+ HRDBG("-> MBR PROVIDER Name: %s", pp->lg_name);
+ HRDBG("Mediasize: %jd",
+ (intmax_t)pp->lg_mediasize / 1024);
+ HRDBG("Sectorsize: %u", pp->lg_sectorsize);
+ HRDBG("Mode: %s", pp->lg_mode);
+ HRDBG("CONFIG: %s: %s",
+ conf->lg_name, conf->lg_val);
+
+ handle_chunk(ds_index, pp->lg_name,
+ pp->lg_mediasize);
+ }
+ }
+ }
+}
+
+/**
+ * Process all BSD-type partitions from the given disk.
+ */
+static void
+get_bsd_sun(struct gclass *classp, int32_t ds_index, const char *disk_dev_name)
+{
+ struct ggeom *gp;
+ struct gprovider *pp;
+
+ LIST_FOREACH(gp, &classp->lg_geom, lg_geom) {
+ /*
+ * We are only interested in those geoms starting with
+ * the disk_dev_name passed as parameter to this function.
+ */
+ if (strncmp(gp->lg_name, disk_dev_name,
+ strlen(disk_dev_name)) != 0)
+ continue;
+
+ LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
+ if (pp->lg_name == NULL)
+ continue;
+ handle_chunk(ds_index, pp->lg_name, pp->lg_mediasize);
+ }
+ }
+}
+
+/**
+ * Called from the DiskStorage table for every row. Open the GEOM(4) framework
+ * and process all the partitions in it.
+ * ds_index is the index into the DiskStorage table.
+ * This is done in two steps: for non BSD partitions the geom class "MBR" is
+ * used, for our BSD slices the "BSD" geom class.
*/
void
partition_tbl_handle_disk(int32_t ds_index, const char *disk_dev_name)
{
- struct disk *disk;
- struct chunk *chunk;
- struct chunk *partt;
+ struct gmesh mesh; /* GEOM userland tree */
+ struct gclass *classp;
+ int error;
assert(disk_dev_name != NULL);
assert(ds_index > 0);
- if ((disk = Open_Disk(disk_dev_name)) == NULL) {
- syslog(LOG_ERR, "%s: cannot Open_Disk()", disk_dev_name);
+ HRDBG("===> getting partitions for %s <===", disk_dev_name);
+
+ /* try to construct the GEOM tree */
+ if ((error = geom_gettree(&mesh)) != 0) {
+ syslog(LOG_WARNING, "cannot get GEOM tree: %m");
return;
}
- for (chunk = disk->chunks->part; chunk != NULL; chunk = chunk->next) {
- handle_chunk(ds_index, chunk, disk);
- for (partt = chunk->part; partt != NULL; partt = partt->next)
- handle_chunk(ds_index, partt, disk);
- }
- Free_Disk(disk);
+ /*
+ * First try the GEOM "MBR" class.
+ * This is needed for non-BSD slices (aka partitions)
+ * on PC architectures.
+ */
+ if ((classp = find_class(&mesh, "MBR")) != NULL) {
+ get_mbr(classp, ds_index, disk_dev_name);
+ } else {
+ HRDBG("cannot find \"MBR\" geom class");
+ }
+
+ /*
+ * Get the "BSD" GEOM class.
+ * Here we'll find all the info needed about the BSD slices.
+ */
+ if ((classp = find_class(&mesh, "BSD")) != NULL) {
+ get_bsd_sun(classp, ds_index, disk_dev_name);
+ } else {
+ /* no problem on sparc64 */
+ HRDBG("cannot find \"BSD\" geom class");
+ }
+
+ /*
+ * Get the "SUN" GEOM class.
+ * Here we'll find all the info needed about the BSD slices.
+ */
+ if ((classp = find_class(&mesh, "SUN")) != NULL) {
+ get_bsd_sun(classp, ds_index, disk_dev_name);
+ } else {
+ /* no problem on i386 */
+ HRDBG("cannot find \"SUN\" geom class");
+ }
+
+ geom_deletetree(&mesh);
}
/**
OpenPOWER on IntegriCloud