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; +} +  | 
