geom_stats.c revision 110545
1110545Sphk/*- 2110545Sphk * Copyright (c) 2003 Poul-Henning Kamp 3110545Sphk * All rights reserved. 4110545Sphk * 5110545Sphk * Redistribution and use in source and binary forms, with or without 6110545Sphk * modification, are permitted provided that the following conditions 7110545Sphk * are met: 8110545Sphk * 1. Redistributions of source code must retain the above copyright 9110545Sphk * notice, this list of conditions and the following disclaimer. 10110545Sphk * 2. Redistributions in binary form must reproduce the above copyright 11110545Sphk * notice, this list of conditions and the following disclaimer in the 12110545Sphk * documentation and/or other materials provided with the distribution. 13110545Sphk * 3. The names of the authors may not be used to endorse or promote 14110545Sphk * products derived from this software without specific prior written 15110545Sphk * permission. 16110545Sphk * 17110545Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18110545Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19110545Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20110545Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21110545Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22110545Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23110545Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24110545Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25110545Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26110545Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27110545Sphk * SUCH DAMAGE. 28110545Sphk * 29110545Sphk * $FreeBSD: head/lib/libgeom/geom_stats.c 110545 2003-02-08 15:15:56Z phk $ 30110545Sphk */ 31110545Sphk 32110545Sphk#include <paths.h> 33110545Sphk#include <errno.h> 34110545Sphk#include <fcntl.h> 35110545Sphk#include <stdlib.h> 36110545Sphk#include <string.h> 37110545Sphk#include <unistd.h> 38110545Sphk#include <libgeom.h> 39110545Sphk 40110545Sphk#include <sys/mman.h> 41110545Sphk#include <sys/time.h> 42110545Sphk#include <sys/types.h> 43110545Sphk 44110545Sphk#include <geom/geom_stats.h> 45110545Sphk#if 0 46110545Sphk#include <stdio.h> 47110545Sphk#include <stdint.h> 48110545Sphk#include <err.h> 49110545Sphk#endif 50110545Sphk 51110545Sphk/************************************************************/ 52110545Sphkstatic uint npages, pagesize, spp; 53110545Sphkstatic int statsfd = -1; 54110545Sphkstatic u_char *statp; 55110545Sphk 56110545Sphkvoid 57110545Sphkgeom_stats_close(void) 58110545Sphk{ 59110545Sphk if (statsfd == -1) 60110545Sphk return; 61110545Sphk munmap(statp, npages *pagesize); 62110545Sphk statp = NULL; 63110545Sphk close (statsfd); 64110545Sphk statsfd = -1; 65110545Sphk} 66110545Sphk 67110545Sphkvoid 68110545Sphkgeom_stats_resync(void) 69110545Sphk{ 70110545Sphk void *p; 71110545Sphk 72110545Sphk if (statsfd == -1) 73110545Sphk return; 74110545Sphk for (;;) { 75110545Sphk p = mmap(statp, (npages + 1) * pagesize, 76110545Sphk PROT_READ, 0, statsfd, 0); 77110545Sphk if (p == MAP_FAILED) 78110545Sphk break; 79110545Sphk else 80110545Sphk statp = p; 81110545Sphk npages++; 82110545Sphk } 83110545Sphk} 84110545Sphk 85110545Sphkint 86110545Sphkgeom_stats_open(void) 87110545Sphk{ 88110545Sphk int error; 89110545Sphk void *p; 90110545Sphk 91110545Sphk if (statsfd != -1) 92110545Sphk return (EBUSY); 93110545Sphk statsfd = open(_PATH_DEV GEOM_STATS_DEVICE, O_RDONLY); 94110545Sphk if (statsfd < 0) 95110545Sphk return (errno); 96110545Sphk pagesize = getpagesize(); 97110545Sphk spp = pagesize / sizeof(struct g_stat); 98110545Sphk p = mmap(NULL, pagesize, PROT_READ, 0, statsfd, 0); 99110545Sphk if (p == MAP_FAILED) { 100110545Sphk error = errno; 101110545Sphk close(statsfd); 102110545Sphk statsfd = -1; 103110545Sphk errno = error; 104110545Sphk return (error); 105110545Sphk } 106110545Sphk statp = p; 107110545Sphk npages = 1; 108110545Sphk geom_stats_resync(); 109110545Sphk return (0); 110110545Sphk} 111110545Sphk 112110545Sphkstruct snapshot { 113110545Sphk u_char *ptr; 114110545Sphk uint pages; 115110545Sphk uint pagesize; 116110545Sphk uint perpage; 117110545Sphk struct timespec time; 118110545Sphk /* used by getnext: */ 119110545Sphk uint u, v; 120110545Sphk}; 121110545Sphk 122110545Sphkvoid * 123110545Sphkgeom_stats_snapshot_get(void) 124110545Sphk{ 125110545Sphk struct snapshot *sp; 126110545Sphk 127110545Sphk sp = malloc(sizeof *sp); 128110545Sphk if (sp == NULL) 129110545Sphk return (NULL); 130110545Sphk memset(sp, 0, sizeof *sp); 131110545Sphk sp->ptr = malloc(pagesize * npages); 132110545Sphk if (sp->ptr == NULL) { 133110545Sphk free(sp); 134110545Sphk return (NULL); 135110545Sphk } 136110545Sphk memset(sp->ptr, 0, pagesize * npages); /* page in, cache */ 137110545Sphk clock_gettime(CLOCK_REALTIME, &sp->time); 138110545Sphk memset(sp->ptr, 0, pagesize * npages); /* page in, cache */ 139110545Sphk memcpy(sp->ptr, statp, pagesize * npages); 140110545Sphk sp->pages = npages; 141110545Sphk sp->perpage = spp; 142110545Sphk sp->pagesize = pagesize; 143110545Sphk return (sp); 144110545Sphk} 145110545Sphk 146110545Sphkvoid 147110545Sphkgeom_stats_snapshot_free(void *arg) 148110545Sphk{ 149110545Sphk struct snapshot *sp; 150110545Sphk 151110545Sphk sp = arg; 152110545Sphk free(sp->ptr); 153110545Sphk free(sp); 154110545Sphk} 155110545Sphk 156110545Sphkvoid 157110545Sphkgeom_stats_snapshot_timestamp(void *arg, struct timespec *tp) 158110545Sphk{ 159110545Sphk struct snapshot *sp; 160110545Sphk 161110545Sphk sp = arg; 162110545Sphk *tp = sp->time; 163110545Sphk} 164110545Sphk 165110545Sphkvoid 166110545Sphkgeom_stats_snapshot_reset(void *arg) 167110545Sphk{ 168110545Sphk struct snapshot *sp; 169110545Sphk 170110545Sphk sp = arg; 171110545Sphk sp->u = sp->v = 0; 172110545Sphk} 173110545Sphk 174110545Sphkstruct g_stat * 175110545Sphkgeom_stats_snapshot_next(void *arg) 176110545Sphk{ 177110545Sphk struct g_stat *gsp; 178110545Sphk struct snapshot *sp; 179110545Sphk 180110545Sphk sp = arg; 181110545Sphk gsp = (struct g_stat *) 182110545Sphk (sp->ptr + sp->u * pagesize + sp->v * sizeof *gsp); 183110545Sphk if (++sp->v >= sp->perpage) { 184110545Sphk if (++sp->u >= sp->pages) 185110545Sphk return (NULL); 186110545Sphk else 187110545Sphk sp->v = 0; 188110545Sphk } 189110545Sphk return (gsp); 190110545Sphk} 191