1154133Sharti/*- 2154133Sharti * Copyright (c) 2005-2006 The FreeBSD Project 3154133Sharti * All rights reserved. 4154133Sharti * 5154133Sharti * Author: Victor Cruceru <soc-victor@freebsd.org> 6154133Sharti * 7154133Sharti * Redistribution of this software and documentation and use in source and 8154133Sharti * binary forms, with or without modification, are permitted provided that 9154133Sharti * the following conditions are met: 10154133Sharti * 11154133Sharti * 1. Redistributions of source code or documentation must retain the above 12154133Sharti * copyright notice, this list of conditions and the following disclaimer. 13154133Sharti * 2. Redistributions in binary form must reproduce the above copyright 14154133Sharti * notice, this list of conditions and the following disclaimer in the 15154133Sharti * documentation and/or other materials provided with the distribution. 16154133Sharti * 17154133Sharti * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18154133Sharti * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19154133Sharti * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20154133Sharti * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21154133Sharti * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22154133Sharti * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23154133Sharti * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24154133Sharti * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25154133Sharti * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26154133Sharti * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27154133Sharti * SUCH DAMAGE. 28154133Sharti * 29154133Sharti * $FreeBSD: stable/10/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_partition_tbl.c 344747 2019-03-04 03:38:43Z avos $ 30154133Sharti */ 31154133Sharti 32154133Sharti/* 33154133Sharti * Host Resources MIB: hrPartitionTable implementation for SNMPd. 34154133Sharti */ 35154133Sharti 36154133Sharti#include <sys/types.h> 37154133Sharti#include <sys/limits.h> 38154133Sharti 39154133Sharti#include <assert.h> 40154133Sharti#include <err.h> 41154856Sharti#include <inttypes.h> 42154856Sharti#include <libgeom.h> 43154133Sharti#include <paths.h> 44154133Sharti#include <stdlib.h> 45154133Sharti#include <string.h> 46154133Sharti#include <syslog.h> 47160341Sharti#include <sysexits.h> 48154133Sharti 49154133Sharti#include "hostres_snmp.h" 50154133Sharti#include "hostres_oid.h" 51154133Sharti#include "hostres_tree.h" 52154133Sharti 53154856Sharti#ifdef PC98 54160341Sharti#define HR_FREEBSD_PART_TYPE 0xc494 55154856Sharti#else 56154856Sharti#define HR_FREEBSD_PART_TYPE 165 57154856Sharti#endif 58154856Sharti 59160341Sharti/* Maximum length for label and id including \0 */ 60160341Sharti#define PART_STR_MLEN (128 + 1) 61160341Sharti 62154133Sharti/* 63154133Sharti * One row in the hrPartitionTable 64154133Sharti */ 65154133Shartistruct partition_entry { 66160341Sharti asn_subid_t index[2]; 67160341Sharti u_char *label; /* max allocated len will be PART_STR_MLEN */ 68160341Sharti u_char *id; /* max allocated len will be PART_STR_MLEN */ 69154133Sharti int32_t size; 70154133Sharti int32_t fs_Index; 71154133Sharti TAILQ_ENTRY(partition_entry) link; 72160341Sharti#define HR_PARTITION_FOUND 0x001 73154133Sharti uint32_t flags; 74154133Sharti}; 75154133ShartiTAILQ_HEAD(partition_tbl, partition_entry); 76154133Sharti 77154133Sharti/* 78154133Sharti * This table is used to get a consistent indexing. It saves the name -> index 79154133Sharti * mapping while we rebuild the partition table. 80154133Sharti */ 81154133Shartistruct partition_map_entry { 82160341Sharti int32_t index; /* partition_entry::index */ 83160341Sharti u_char *id; /* max allocated len will be PART_STR_MLEN */ 84154133Sharti 85154133Sharti /* 86154133Sharti * next may be NULL if the respective partition_entry 87154133Sharti * is (temporally) gone. 88154133Sharti */ 89154133Sharti struct partition_entry *entry; 90154133Sharti STAILQ_ENTRY(partition_map_entry) link; 91154133Sharti}; 92154133ShartiSTAILQ_HEAD(partition_map, partition_map_entry); 93154133Sharti 94154133Sharti/* Mapping table for consistent indexing */ 95154133Shartistatic struct partition_map partition_map = 96154133Sharti STAILQ_HEAD_INITIALIZER(partition_map); 97154133Sharti 98154133Sharti/* THE partition table. */ 99154133Shartistatic struct partition_tbl partition_tbl = 100154133Sharti TAILQ_HEAD_INITIALIZER(partition_tbl); 101154133Sharti 102154133Sharti/* next int available for indexing the hrPartitionTable */ 103154133Shartistatic uint32_t next_partition_index = 1; 104154133Sharti 105160341Sharti/* 106160341Sharti * Partition_entry_cmp is used for INSERT_OBJECT_FUNC_LINK 107160341Sharti * macro. 108160341Sharti */ 109160341Shartistatic int 110160341Shartipartition_entry_cmp(const struct partition_entry *a, 111160341Sharti const struct partition_entry *b) 112160341Sharti{ 113160341Sharti assert(a != NULL); 114160341Sharti assert(b != NULL); 115160341Sharti 116160341Sharti if (a->index[0] < b->index[0]) 117160341Sharti return (-1); 118160341Sharti 119160341Sharti if (a->index[0] > b->index[0]) 120160341Sharti return (+1); 121160341Sharti 122160341Sharti if (a->index[1] < b->index[1]) 123160341Sharti return (-1); 124160341Sharti 125160341Sharti if (a->index[1] > b->index[1]) 126160341Sharti return (+1); 127160341Sharti 128160341Sharti return (0); 129160341Sharti} 130160341Sharti 131160341Sharti/* 132160341Sharti * Partition_idx_cmp is used for NEXT_OBJECT_FUNC and FIND_OBJECT_FUNC 133160341Sharti * macros 134160341Sharti */ 135160341Shartistatic int 136160341Shartipartition_idx_cmp(const struct asn_oid *oid, u_int sub, 137160341Sharti const struct partition_entry *entry) 138160341Sharti{ 139160341Sharti u_int i; 140160341Sharti 141160341Sharti for (i = 0; i < 2 && i < oid->len - sub; i++) { 142160341Sharti if (oid->subs[sub + i] < entry->index[i]) 143160341Sharti return (-1); 144160341Sharti if (oid->subs[sub + i] > entry->index[i]) 145160341Sharti return (+1); 146160341Sharti } 147160341Sharti if (oid->len - sub < 2) 148160341Sharti return (-1); 149160341Sharti if (oid->len - sub > 2) 150160341Sharti return (+1); 151160341Sharti 152160341Sharti return (0); 153160341Sharti} 154160341Sharti 155154133Sharti/** 156154133Sharti * Create a new partition table entry 157154133Sharti */ 158154133Shartistatic struct partition_entry * 159154856Shartipartition_entry_create(int32_t ds_index, const char *chunk_name) 160154133Sharti{ 161154133Sharti struct partition_entry *entry; 162160341Sharti struct partition_map_entry *map; 163160341Sharti size_t id_len; 164154133Sharti 165154133Sharti /* sanity checks */ 166154856Sharti assert(chunk_name != NULL); 167154856Sharti if (chunk_name == NULL || chunk_name[0] == '\0') 168154133Sharti return (NULL); 169154133Sharti 170154133Sharti /* check whether we already have seen this partition */ 171154133Sharti STAILQ_FOREACH(map, &partition_map, link) 172160341Sharti if (strcmp(map->id, chunk_name) == 0) 173154133Sharti break; 174154133Sharti 175154133Sharti if (map == NULL) { 176154133Sharti /* new object - get a new index and create a map */ 177160341Sharti 178154133Sharti if (next_partition_index > INT_MAX) { 179160341Sharti /* Unrecoverable error - die clean and quicly*/ 180310900Sngie syslog(LOG_ERR, "%s: hrPartitionTable index wrap", 181154133Sharti __func__); 182160341Sharti errx(EX_SOFTWARE, "hrPartitionTable index wrap"); 183154133Sharti } 184154133Sharti 185154133Sharti if ((map = malloc(sizeof(*map))) == NULL) { 186154133Sharti syslog(LOG_ERR, "hrPartitionTable: %s: %m", __func__); 187154133Sharti return (NULL); 188154133Sharti } 189154133Sharti 190160341Sharti id_len = strlen(chunk_name) + 1; 191160341Sharti if (id_len > PART_STR_MLEN) 192160341Sharti id_len = PART_STR_MLEN; 193160341Sharti 194160341Sharti if ((map->id = malloc(id_len)) == NULL) { 195160341Sharti free(map); 196160341Sharti return (NULL); 197160341Sharti } 198160341Sharti 199154133Sharti map->index = next_partition_index++; 200154133Sharti 201160341Sharti strlcpy(map->id, chunk_name, id_len); 202154133Sharti 203160341Sharti map->entry = NULL; 204160341Sharti 205154133Sharti STAILQ_INSERT_TAIL(&partition_map, map, link); 206154133Sharti 207154133Sharti HRDBG("%s added into hrPartitionMap at index=%d", 208154856Sharti chunk_name, map->index); 209154133Sharti 210154133Sharti } else { 211154133Sharti HRDBG("%s exists in hrPartitionMap index=%d", 212154856Sharti chunk_name, map->index); 213154133Sharti } 214154133Sharti 215160341Sharti if ((entry = malloc(sizeof(*entry))) == NULL) { 216160341Sharti syslog(LOG_WARNING, "hrPartitionTable: %s: %m", __func__); 217160341Sharti return (NULL); 218160341Sharti } 219160341Sharti memset(entry, 0, sizeof(*entry)); 220160341Sharti 221154133Sharti /* create the index */ 222160341Sharti entry->index[0] = ds_index; 223160341Sharti entry->index[1] = map->index; 224154133Sharti 225160341Sharti map->entry = entry; 226154133Sharti 227160341Sharti if ((entry->id = strdup(map->id)) == NULL) { 228160341Sharti free(entry); 229160341Sharti return (NULL); 230160341Sharti } 231154133Sharti 232160341Sharti /* 233160341Sharti * reuse id_len from here till the end of this function 234160341Sharti * for partition_entry::label 235160341Sharti */ 236160341Sharti id_len = strlen(_PATH_DEV) + strlen(chunk_name) + 1; 237154133Sharti 238160341Sharti if (id_len > PART_STR_MLEN) 239160341Sharti id_len = PART_STR_MLEN; 240160341Sharti 241160341Sharti if ((entry->label = malloc(id_len )) == NULL) { 242160341Sharti free(entry->id); 243160341Sharti free(entry); 244160341Sharti return (NULL); 245160341Sharti } 246160341Sharti 247160341Sharti snprintf(entry->label, id_len, "%s%s", _PATH_DEV, chunk_name); 248160341Sharti 249160341Sharti INSERT_OBJECT_FUNC_LINK(entry, &partition_tbl, link, 250160341Sharti partition_entry_cmp); 251160341Sharti 252154133Sharti return (entry); 253154133Sharti} 254154133Sharti 255154133Sharti/** 256154133Sharti * Delete a partition table entry but keep the map entry intact. 257154133Sharti */ 258154133Shartistatic void 259154133Shartipartition_entry_delete(struct partition_entry *entry) 260154133Sharti{ 261154133Sharti struct partition_map_entry *map; 262154133Sharti 263154133Sharti assert(entry != NULL); 264154133Sharti 265154133Sharti TAILQ_REMOVE(&partition_tbl, entry, link); 266154133Sharti STAILQ_FOREACH(map, &partition_map, link) 267154133Sharti if (map->entry == entry) { 268154133Sharti map->entry = NULL; 269154133Sharti break; 270154133Sharti } 271160341Sharti free(entry->id); 272160341Sharti free(entry->label); 273154133Sharti free(entry); 274154133Sharti} 275154133Sharti 276154133Sharti/** 277154133Sharti * Find a partition table entry by name. If none is found, return NULL. 278154133Sharti */ 279154133Shartistatic struct partition_entry * 280154133Shartipartition_entry_find_by_name(const char *name) 281154133Sharti{ 282154133Sharti struct partition_entry *entry = NULL; 283154133Sharti 284154133Sharti TAILQ_FOREACH(entry, &partition_tbl, link) 285154133Sharti if (strcmp(entry->id, name) == 0) 286154133Sharti return (entry); 287154133Sharti 288154133Sharti return (NULL); 289154133Sharti} 290154133Sharti 291154133Sharti/** 292154133Sharti * Find a partition table entry by label. If none is found, return NULL. 293154133Sharti */ 294154133Shartistatic struct partition_entry * 295154133Shartipartition_entry_find_by_label(const char *name) 296154133Sharti{ 297154133Sharti struct partition_entry *entry = NULL; 298154133Sharti 299154133Sharti TAILQ_FOREACH(entry, &partition_tbl, link) 300154133Sharti if (strcmp(entry->label, name) == 0) 301154133Sharti return (entry); 302154133Sharti 303154133Sharti return (NULL); 304154133Sharti} 305154133Sharti 306154133Sharti/** 307154856Sharti * Process a chunk from libgeom(4). A chunk is either a slice or a partition. 308154133Sharti * If necessary create a new partition table entry for it. In any case 309154133Sharti * set the size field of the entry and set the FOUND flag. 310154133Sharti */ 311154133Shartistatic void 312154856Shartihandle_chunk(int32_t ds_index, const char *chunk_name, off_t chunk_size) 313154133Sharti{ 314160341Sharti struct partition_entry *entry; 315154133Sharti daddr_t k_size; 316154133Sharti 317154856Sharti assert(chunk_name != NULL); 318154856Sharti assert(chunk_name[0] != '\0'); 319344747Savos if (chunk_name == NULL || chunk_name[0] == '\0') 320154133Sharti return; 321154133Sharti 322154856Sharti HRDBG("ANALYZE chunk %s", chunk_name); 323154133Sharti 324154856Sharti if ((entry = partition_entry_find_by_name(chunk_name)) == NULL) 325154856Sharti if ((entry = partition_entry_create(ds_index, 326154856Sharti chunk_name)) == NULL) 327154133Sharti return; 328154133Sharti 329154133Sharti entry->flags |= HR_PARTITION_FOUND; 330154133Sharti 331154133Sharti /* actual size may overflow the SNMP type */ 332154856Sharti k_size = chunk_size / 1024; 333154856Sharti entry->size = (k_size > (off_t)INT_MAX ? INT_MAX : k_size); 334154133Sharti} 335154133Sharti 336154133Sharti/** 337154133Sharti * Start refreshing the partition table. A call to this function will 338154133Sharti * be followed by a call to handleDiskStorage() for every disk, followed 339154133Sharti * by a single call to the post_refresh function. 340154133Sharti */ 341154133Shartivoid 342154133Shartipartition_tbl_pre_refresh(void) 343154133Sharti{ 344160341Sharti struct partition_entry *entry; 345154133Sharti 346154133Sharti /* mark each entry as missing */ 347154133Sharti TAILQ_FOREACH(entry, &partition_tbl, link) 348154133Sharti entry->flags &= ~HR_PARTITION_FOUND; 349154133Sharti} 350154133Sharti 351154133Sharti/** 352154856Sharti * Try to find a geom(4) class by its name. Returns a pointer to that 353154856Sharti * class if found NULL otherways. 354154133Sharti */ 355154856Shartistatic struct gclass * 356154856Shartifind_class(struct gmesh *mesh, const char *name) 357154856Sharti{ 358154856Sharti struct gclass *classp; 359154856Sharti 360154856Sharti LIST_FOREACH(classp, &mesh->lg_class, lg_class) 361154856Sharti if (strcmp(classp->lg_name, name) == 0) 362154856Sharti return (classp); 363154856Sharti return (NULL); 364154856Sharti} 365154856Sharti 366154856Sharti/** 367154856Sharti * Process all MBR-type partitions from the given disk. 368154856Sharti */ 369154856Shartistatic void 370154856Shartiget_mbr(struct gclass *classp, int32_t ds_index, const char *disk_dev_name) 371154856Sharti{ 372154856Sharti struct ggeom *gp; 373154856Sharti struct gprovider *pp; 374154856Sharti struct gconfig *conf; 375154856Sharti long part_type; 376154856Sharti 377154856Sharti LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { 378154856Sharti /* We are only interested in partitions from this disk */ 379154856Sharti if (strcmp(gp->lg_name, disk_dev_name) != 0) 380154856Sharti continue; 381154856Sharti 382154856Sharti /* 383154856Sharti * Find all the non-BSD providers (these are handled in get_bsd) 384154856Sharti */ 385154856Sharti LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { 386154856Sharti LIST_FOREACH(conf, &pp->lg_config, lg_config) { 387154856Sharti if (conf->lg_name == NULL || 388154856Sharti conf->lg_val == NULL || 389154856Sharti strcmp(conf->lg_name, "type") != 0) 390154856Sharti continue; 391154856Sharti 392154856Sharti /* 393154856Sharti * We are not interested in BSD partitions 394154856Sharti * (ie ad0s1 is not interesting at this point). 395154856Sharti * We'll take care of them in detail (slice 396154856Sharti * by slice) in get_bsd. 397154856Sharti */ 398154856Sharti part_type = strtol(conf->lg_val, NULL, 10); 399154856Sharti if (part_type == HR_FREEBSD_PART_TYPE) 400154856Sharti break; 401154856Sharti HRDBG("-> MBR PROVIDER Name: %s", pp->lg_name); 402154856Sharti HRDBG("Mediasize: %jd", 403154856Sharti (intmax_t)pp->lg_mediasize / 1024); 404154856Sharti HRDBG("Sectorsize: %u", pp->lg_sectorsize); 405154856Sharti HRDBG("Mode: %s", pp->lg_mode); 406154856Sharti HRDBG("CONFIG: %s: %s", 407154856Sharti conf->lg_name, conf->lg_val); 408154856Sharti 409154856Sharti handle_chunk(ds_index, pp->lg_name, 410154856Sharti pp->lg_mediasize); 411154856Sharti } 412154856Sharti } 413154856Sharti } 414154856Sharti} 415154856Sharti 416154856Sharti/** 417154856Sharti * Process all BSD-type partitions from the given disk. 418154856Sharti */ 419154856Shartistatic void 420154856Shartiget_bsd_sun(struct gclass *classp, int32_t ds_index, const char *disk_dev_name) 421154856Sharti{ 422154856Sharti struct ggeom *gp; 423154856Sharti struct gprovider *pp; 424154856Sharti 425154856Sharti LIST_FOREACH(gp, &classp->lg_geom, lg_geom) { 426154856Sharti /* 427154856Sharti * We are only interested in those geoms starting with 428154856Sharti * the disk_dev_name passed as parameter to this function. 429154856Sharti */ 430154856Sharti if (strncmp(gp->lg_name, disk_dev_name, 431154856Sharti strlen(disk_dev_name)) != 0) 432154856Sharti continue; 433154856Sharti 434154856Sharti LIST_FOREACH(pp, &gp->lg_provider, lg_provider) { 435154856Sharti if (pp->lg_name == NULL) 436154856Sharti continue; 437154856Sharti handle_chunk(ds_index, pp->lg_name, pp->lg_mediasize); 438154856Sharti } 439154856Sharti } 440154856Sharti} 441154856Sharti 442154856Sharti/** 443154856Sharti * Called from the DiskStorage table for every row. Open the GEOM(4) framework 444154856Sharti * and process all the partitions in it. 445154856Sharti * ds_index is the index into the DiskStorage table. 446154856Sharti * This is done in two steps: for non BSD partitions the geom class "MBR" is 447154856Sharti * used, for our BSD slices the "BSD" geom class. 448154856Sharti */ 449154133Shartivoid 450154133Shartipartition_tbl_handle_disk(int32_t ds_index, const char *disk_dev_name) 451154133Sharti{ 452154856Sharti struct gmesh mesh; /* GEOM userland tree */ 453154856Sharti struct gclass *classp; 454154856Sharti int error; 455154133Sharti 456154133Sharti assert(disk_dev_name != NULL); 457154133Sharti assert(ds_index > 0); 458154133Sharti 459160341Sharti HRDBG("===> getting partitions for %s <===", disk_dev_name); 460154856Sharti 461154856Sharti /* try to construct the GEOM tree */ 462154856Sharti if ((error = geom_gettree(&mesh)) != 0) { 463154856Sharti syslog(LOG_WARNING, "cannot get GEOM tree: %m"); 464154133Sharti return; 465154133Sharti } 466154133Sharti 467154856Sharti /* 468154856Sharti * First try the GEOM "MBR" class. 469154856Sharti * This is needed for non-BSD slices (aka partitions) 470154856Sharti * on PC architectures. 471154856Sharti */ 472154856Sharti if ((classp = find_class(&mesh, "MBR")) != NULL) { 473154856Sharti get_mbr(classp, ds_index, disk_dev_name); 474154856Sharti } else { 475154856Sharti HRDBG("cannot find \"MBR\" geom class"); 476154856Sharti } 477154856Sharti 478154856Sharti /* 479154856Sharti * Get the "BSD" GEOM class. 480154856Sharti * Here we'll find all the info needed about the BSD slices. 481154856Sharti */ 482154856Sharti if ((classp = find_class(&mesh, "BSD")) != NULL) { 483154856Sharti get_bsd_sun(classp, ds_index, disk_dev_name); 484154856Sharti } else { 485154856Sharti /* no problem on sparc64 */ 486154856Sharti HRDBG("cannot find \"BSD\" geom class"); 487154856Sharti } 488154856Sharti 489154856Sharti /* 490154856Sharti * Get the "SUN" GEOM class. 491154856Sharti * Here we'll find all the info needed about the BSD slices. 492154856Sharti */ 493154856Sharti if ((classp = find_class(&mesh, "SUN")) != NULL) { 494154856Sharti get_bsd_sun(classp, ds_index, disk_dev_name); 495154856Sharti } else { 496154856Sharti /* no problem on i386 */ 497154856Sharti HRDBG("cannot find \"SUN\" geom class"); 498154856Sharti } 499154856Sharti 500154856Sharti geom_deletetree(&mesh); 501154133Sharti} 502154133Sharti 503154133Sharti/** 504154133Sharti * Finish refreshing the table. 505154133Sharti */ 506154133Shartivoid 507154133Shartipartition_tbl_post_refresh(void) 508154133Sharti{ 509154133Sharti struct partition_entry *e, *etmp; 510154133Sharti 511154133Sharti /* 512154133Sharti * Purge items that disappeared 513154133Sharti */ 514154133Sharti TAILQ_FOREACH_SAFE(e, &partition_tbl, link, etmp) 515154133Sharti if (!(e->flags & HR_PARTITION_FOUND)) 516154133Sharti partition_entry_delete(e); 517154133Sharti} 518154133Sharti 519154133Sharti/* 520154133Sharti * Finalization routine for hrPartitionTable 521154133Sharti * It destroys the lists and frees any allocated heap memory 522154133Sharti */ 523154133Shartivoid 524154133Shartifini_partition_tbl(void) 525154133Sharti{ 526154133Sharti struct partition_map_entry *m; 527154133Sharti 528160341Sharti while ((m = STAILQ_FIRST(&partition_map)) != NULL) { 529154133Sharti STAILQ_REMOVE_HEAD(&partition_map, link); 530154133Sharti if(m->entry != NULL) { 531154133Sharti TAILQ_REMOVE(&partition_tbl, m->entry, link); 532160341Sharti free(m->entry->id); 533160341Sharti free(m->entry->label); 534154133Sharti free(m->entry); 535154133Sharti } 536160341Sharti free(m->id); 537154133Sharti free(m); 538160341Sharti } 539154133Sharti assert(TAILQ_EMPTY(&partition_tbl)); 540154133Sharti} 541154133Sharti 542154133Sharti/** 543154133Sharti * Called from the file system code to insert the file system table index 544154133Sharti * into the partition table entry. Note, that an partition table entry exists 545154133Sharti * only for local file systems. 546154133Sharti */ 547154133Shartivoid 548154133Shartihandle_partition_fs_index(const char *name, int32_t fs_idx) 549154133Sharti{ 550154133Sharti struct partition_entry *entry; 551154133Sharti 552154133Sharti if ((entry = partition_entry_find_by_label(name)) == NULL) { 553154133Sharti HRDBG("%s IS MISSING from hrPartitionTable", name); 554154133Sharti return; 555154133Sharti } 556154133Sharti HRDBG("%s [FS index = %d] IS in hrPartitionTable", name, fs_idx); 557154133Sharti entry->fs_Index = fs_idx; 558154133Sharti} 559154133Sharti 560154133Sharti/* 561154133Sharti * This is the implementation for a generated (by our SNMP tool) 562154133Sharti * function prototype, see hostres_tree.h 563154133Sharti * It handles the SNMP operations for hrPartitionTable 564154133Sharti */ 565154133Shartiint 566154133Shartiop_hrPartitionTable(struct snmp_context *ctx __unused, struct snmp_value *value, 567154133Sharti u_int sub, u_int iidx __unused, enum snmp_op op) 568154133Sharti{ 569154133Sharti struct partition_entry *entry; 570154133Sharti 571154133Sharti /* 572154133Sharti * Refresh the disk storage table (which refreshes the partition 573154133Sharti * table) if necessary. 574154133Sharti */ 575154133Sharti refresh_disk_storage_tbl(0); 576154133Sharti 577154133Sharti switch (op) { 578154133Sharti 579154133Sharti case SNMP_OP_GETNEXT: 580160341Sharti if ((entry = NEXT_OBJECT_FUNC(&partition_tbl, 581160341Sharti &value->var, sub, partition_idx_cmp)) == NULL) 582154133Sharti return (SNMP_ERR_NOSUCHNAME); 583154133Sharti 584160341Sharti value->var.len = sub + 2; 585160341Sharti value->var.subs[sub] = entry->index[0]; 586160341Sharti value->var.subs[sub + 1] = entry->index[1]; 587160341Sharti 588154133Sharti goto get; 589154133Sharti 590154133Sharti case SNMP_OP_GET: 591160341Sharti if ((entry = FIND_OBJECT_FUNC(&partition_tbl, 592160341Sharti &value->var, sub, partition_idx_cmp)) == NULL) 593154133Sharti return (SNMP_ERR_NOSUCHNAME); 594154133Sharti goto get; 595154133Sharti 596154133Sharti case SNMP_OP_SET: 597160341Sharti if ((entry = FIND_OBJECT_FUNC(&partition_tbl, 598160341Sharti &value->var, sub, partition_idx_cmp)) == NULL) 599154133Sharti return (SNMP_ERR_NOT_WRITEABLE); 600154133Sharti return (SNMP_ERR_NO_CREATION); 601154133Sharti 602154133Sharti case SNMP_OP_ROLLBACK: 603154133Sharti case SNMP_OP_COMMIT: 604154133Sharti abort(); 605154133Sharti } 606154133Sharti abort(); 607154133Sharti 608154133Sharti get: 609154133Sharti switch (value->var.subs[sub - 1]) { 610154133Sharti 611154133Sharti case LEAF_hrPartitionIndex: 612160341Sharti value->v.integer = entry->index[1]; 613154133Sharti return (SNMP_ERR_NOERROR); 614154133Sharti 615154133Sharti case LEAF_hrPartitionLabel: 616154133Sharti return (string_get(value, entry->label, -1)); 617154133Sharti 618154133Sharti case LEAF_hrPartitionID: 619154133Sharti return(string_get(value, entry->id, -1)); 620154133Sharti 621154133Sharti case LEAF_hrPartitionSize: 622154133Sharti value->v.integer = entry->size; 623154133Sharti return (SNMP_ERR_NOERROR); 624154133Sharti 625154133Sharti case LEAF_hrPartitionFSIndex: 626154133Sharti value->v.integer = entry->fs_Index; 627154133Sharti return (SNMP_ERR_NOERROR); 628154133Sharti } 629154133Sharti abort(); 630154133Sharti} 631