Fix the MIB to use libgeom instead of libdisk.

Submitted by:	Victor Cruceru <soc-victor>
This commit is contained in:
Hartmut Brandt 2006-01-26 10:13:32 +00:00
parent 6267a27838
commit e8689b4ce4
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=154856
3 changed files with 170 additions and 48 deletions

View File

@ -48,7 +48,7 @@ SRCS= hostres_begemot.c \
printcap.c printcap.c
#Not having NDEBUG defined will enable assertions and a lot of output on stderr #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 \ XSYM= host hrStorageOther hrStorageRam hrStorageVirtualMemory \
hrStorageFixedDisk hrStorageRemovableDisk hrStorageFloppyDisk \ hrStorageFixedDisk hrStorageRemovableDisk hrStorageFloppyDisk \
hrStorageCompactDisc hrStorageRamDisk hrStorageFlashMemory \ hrStorageCompactDisc hrStorageRamDisk hrStorageFlashMemory \
@ -69,8 +69,8 @@ MAN= snmp_hostres.3
DEFS= ${MOD}_tree.def DEFS= ${MOD}_tree.def
BMIBS= BEGEMOT-HOSTRES-MIB.txt BMIBS= BEGEMOT-HOSTRES-MIB.txt
DPADD= ${LIBKVM} ${LIBDEVINFO} ${LIBM} ${LIBDISK} ${LIBMEMSTAT} DPADD= ${LIBKVM} ${LIBDEVINFO} ${LIBM} ${LIBGEOM} ${LIBMEMSTAT}
LDADD= -lkvm -ldevinfo -lm -ldisk -lmemstat LDADD= -lkvm -ldevinfo -lm -lgeom -lmemstat
.include <bsd.snmpmod.mk> .include <bsd.snmpmod.mk>

View File

@ -225,11 +225,8 @@ disk_query_disk(struct disk_entry *entry)
mediasize = mediasize / 1024; mediasize = mediasize / 1024;
entry->capacity = (mediasize > INT_MAX ? INT_MAX : mediasize); 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); (void)close(fd);
} }

View File

@ -38,7 +38,8 @@
#include <assert.h> #include <assert.h>
#include <err.h> #include <err.h>
#include <libdisk.h> #include <inttypes.h>
#include <libgeom.h>
#include <paths.h> #include <paths.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -48,6 +49,12 @@
#include "hostres_oid.h" #include "hostres_oid.h"
#include "hostres_tree.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 * One row in the hrPartitionTable
*/ */
@ -95,15 +102,14 @@ static uint32_t next_partition_index = 1;
* Create a new partition table entry * Create a new partition table entry
*/ */
static struct partition_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_entry *entry;
struct partition_map_entry *map = NULL; struct partition_map_entry *map = NULL;
/* sanity checks */ /* sanity checks */
assert(chunk != NULL); assert(chunk_name != NULL);
assert(chunk->name != NULL); if (chunk_name == NULL || chunk_name[0] == '\0')
if (chunk == NULL || chunk->name == NULL || chunk->name[0] == '\0')
return (NULL); return (NULL);
if ((entry = malloc(sizeof(*entry))) == 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 */ /* check whether we already have seen this partition */
STAILQ_FOREACH(map, &partition_map, link) STAILQ_FOREACH(map, &partition_map, link)
if (strcmp(map->id, chunk->name) == 0 ) { if (strcmp(map->id, chunk_name) == 0 ) {
map->entry = entry; map->entry = entry;
break; break;
} }
@ -135,18 +141,17 @@ partition_entry_create(int32_t ds_index, const struct chunk *chunk)
map->index = next_partition_index++; map->index = next_partition_index++;
memset(map->id, 0, sizeof(map->id)); strlcpy(map->id, chunk_name, sizeof(map->id));
strncpy(map->id, chunk->name, sizeof(map->id) - 1);
map->entry = entry; map->entry = entry;
STAILQ_INSERT_TAIL(&partition_map, map, link); STAILQ_INSERT_TAIL(&partition_map, map, link);
HRDBG("%s added into hrPartitionMap at index=%d", HRDBG("%s added into hrPartitionMap at index=%d",
chunk->name, map->index); chunk_name, map->index);
} else { } else {
HRDBG("%s exists in hrPartitionMap index=%d", HRDBG("%s exists in hrPartitionMap index=%d",
chunk->name, map->index); chunk_name, map->index);
} }
/* create the 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[0] = ds_index;
entry->index.subs[1] = map->index; entry->index.subs[1] = map->index;
memset(&entry->id[0], 0, sizeof(entry->id)); strlcpy(entry->id, chunk_name, sizeof(entry->id));
strncpy(entry->id, chunk->name, sizeof(entry->id) - 1);
snprintf(entry->label, sizeof(entry->label) - 1, 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); 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 * 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. * set the size field of the entry and set the FOUND flag.
*/ */
static void static void
handle_chunk(int32_t ds_index, const struct chunk* chunk, handle_chunk(int32_t ds_index, const char *chunk_name, off_t chunk_size)
const struct disk *disk)
{ {
struct partition_entry *entry = NULL; struct partition_entry *entry = NULL;
daddr_t k_size; daddr_t k_size;
assert(chunk != NULL); assert(chunk_name != NULL);
if (chunk == NULL) assert(chunk_name[0] != '\0');
if (chunk_name == NULL || chunk_name == '\0')
return; return;
if (chunk->type == unused) { HRDBG("ANALYZE chunk %s", chunk_name);
HRDBG("SKIP unused chunk %s", chunk->name);
return;
}
HRDBG("ANALYZE chunk %s", chunk->name);
if ((entry = partition_entry_find_by_name(chunk->name)) == NULL) if ((entry = partition_entry_find_by_name(chunk_name)) == NULL)
if ((entry = partition_entry_create(ds_index, chunk)) == NULL) if ((entry = partition_entry_create(ds_index,
chunk_name)) == NULL)
return; return;
entry->flags |= HR_PARTITION_FOUND; entry->flags |= HR_PARTITION_FOUND;
/* actual size may overflow the SNMP type */ /* actual size may overflow the SNMP type */
k_size = chunk->size / (1024 / disk->sector_size); k_size = chunk_size / 1024;
entry->size = (k_size > (daddr_t)INT_MAX ? INT_MAX : k_size); 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 * Try to find a geom(4) class by its name. Returns a pointer to that
* process all the partitions in it. ds_index is the index into the DiskStorage * class if found NULL otherways.
* table. */
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 void
partition_tbl_handle_disk(int32_t ds_index, const char *disk_dev_name) partition_tbl_handle_disk(int32_t ds_index, const char *disk_dev_name)
{ {
struct disk *disk; struct gmesh mesh; /* GEOM userland tree */
struct chunk *chunk; struct gclass *classp;
struct chunk *partt; int error;
assert(disk_dev_name != NULL); assert(disk_dev_name != NULL);
assert(ds_index > 0); assert(ds_index > 0);
if ((disk = Open_Disk(disk_dev_name)) == NULL) { HRDBG("===> getting partitions for %s <===", disk_dev_name);
syslog(LOG_ERR, "%s: cannot Open_Disk()", disk_dev_name);
/* try to construct the GEOM tree */
if ((error = geom_gettree(&mesh)) != 0) {
syslog(LOG_WARNING, "cannot get GEOM tree: %m");
return; return;
} }
for (chunk = disk->chunks->part; chunk != NULL; chunk = chunk->next) { /*
handle_chunk(ds_index, chunk, disk); * First try the GEOM "MBR" class.
for (partt = chunk->part; partt != NULL; partt = partt->next) * This is needed for non-BSD slices (aka partitions)
handle_chunk(ds_index, partt, disk); * on PC architectures.
} */
Free_Disk(disk); 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);
} }
/** /**