diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/Makefile.am | 6 | ||||
-rw-r--r-- | tools/jail-measure.c | 185 |
2 files changed, 191 insertions, 0 deletions
diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..3b856ea --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,6 @@ + +libexec_PROGRAMS = jail-measure + +jail_measure_SOURCES = jail-measure.c ${top_srcdir}/common/hash.c +jail_measure_CFLAGS = -I${top_srcdir} -I${top_srcdir}/common + diff --git a/tools/jail-measure.c b/tools/jail-measure.c new file mode 100644 index 0000000..8a814b6 --- /dev/null +++ b/tools/jail-measure.c @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2008, Stefan Walter + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * 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. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT OWNER 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. + * + * + * CONTRIBUTORS + * Stef Walter <stef@memberwebs.com> + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <err.h> +#include <errno.h> +#include <fts.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <syslog.h> +#include <unistd.h> + +#include "hash.h" + +static uint64_t jail_blocks = 0; +static uint64_t jail_files = 0; +static uint64_t jail_bytes = 0; + +static hsh_t *jail_inodes = NULL; + +static int syslog_facility = 0; + +/* For use in the hash table as a value */ +#define HAVE ((void*)1) + +static void +usage () +{ + fprintf (stderr, "usage: jail-measure [-l syslog] path ...\n"); + exit (2); +} + +static void +emsg (const char *format, ...) +{ + va_list va; + va_start (va, format); + if (syslog_facility) + vsyslog (syslog_facility, format, va); + vwarnx (format, va); + va_end (va); +} + +static int +check_skip_link (FTSENT *f) +{ + unsigned int inode = f->fts_statp->st_ino; + + if (hsh_get (jail_inodes, (void*)inode, HSH_KEY_DIRECT)) { + return 1; + } else { + if (!hsh_set (jail_inodes, (void*)inode, HSH_KEY_DIRECT, HAVE)) { + emsg ("out of memory"); + exit (1); + } + return 0; + } +} + +static void +measure_jail (const char *path) +{ + const char *paths[2] = { path, NULL }; + FTS *fts; + FTSENT *f; + + jail_blocks = 0; + jail_bytes = 0; + hsh_clear (jail_inodes); + + fts = fts_open ((char**)paths, FTS_COMFOLLOW | FTS_PHYSICAL | FTS_XDEV, NULL); + if (fts == NULL) { + emsg ("couldn't access jail path: %s", path); + return; + } + + while ((f = fts_read (fts)) != NULL) { + switch (f->fts_info) { + case FTS_D: + break; + case FTS_DP: + jail_blocks += f->fts_statp->st_blocks; + jail_bytes += f->fts_statp->st_size; + jail_files++; + break; + case FTS_DC: + break; + case FTS_DNR: + case FTS_ERR: + case FTS_NS: + emsg ("couldn't access path: %s: %s", f->fts_path, strerror (f->fts_errno)); + break; + default: + if (f->fts_statp->st_nlink == 1 || !check_skip_link (f)) { + jail_blocks += f->fts_statp->st_blocks; + jail_bytes += f->fts_statp->st_size; + jail_files++; + } + break; + }; + } + + fts_close (fts); + + printf ("jail-space: %llu %s\n", jail_blocks * 512, path); + printf ("jail-files: %llu %s\n", jail_files, path); +} + +int +main (int argc, char* argv[]) +{ + int ch, i; + + /* Parse the arguments nicely */ + while ((ch = getopt (argc, argv, "l:")) != -1) { + switch(ch) { + + /* Log to syslog */ + case 'l': + syslog_facility = atoi (optarg); + break; + + /* Usage information */ + case '?': + default: + usage(); + break; + } + } + + argc -= optind; + argv += optind; + + if (argc < 1) + usage (); + + jail_inodes = hsh_create (); + + for (i = 0; i < argc; ++i) + measure_jail (argv[i]); + + hsh_free (jail_inodes); + + return 0; +} + |