diff options
Diffstat (limited to 'src/fsstone')
l--------- | src/fsstone/.indent.pro | 1 | ||||
-rw-r--r-- | src/fsstone/.printfck | 25 | ||||
-rw-r--r-- | src/fsstone/Makefile.in | 69 | ||||
-rw-r--r-- | src/fsstone/fsstone.c | 242 |
4 files changed, 337 insertions, 0 deletions
diff --git a/src/fsstone/.indent.pro b/src/fsstone/.indent.pro new file mode 120000 index 0000000..5c837ec --- /dev/null +++ b/src/fsstone/.indent.pro @@ -0,0 +1 @@ +../../.indent.pro
\ No newline at end of file diff --git a/src/fsstone/.printfck b/src/fsstone/.printfck new file mode 100644 index 0000000..66016ed --- /dev/null +++ b/src/fsstone/.printfck @@ -0,0 +1,25 @@ +been_here_xt 2 0 +bounce_append 5 0 +cleanup_out_format 1 0 +defer_append 5 0 +mail_command 1 0 +mail_print 1 0 +msg_error 0 0 +msg_fatal 0 0 +msg_info 0 0 +msg_panic 0 0 +msg_warn 0 0 +opened 4 0 +post_mail_fprintf 1 0 +qmgr_message_bounce 2 0 +rec_fprintf 2 0 +sent 4 0 +smtp_cmd 1 0 +smtp_mesg_fail 2 0 +smtp_printf 1 0 +smtp_rcpt_fail 3 0 +smtp_site_fail 2 0 +udp_syslog 1 0 +vstream_fprintf 1 0 +vstream_printf 0 0 +vstring_sprintf 1 0 diff --git a/src/fsstone/Makefile.in b/src/fsstone/Makefile.in new file mode 100644 index 0000000..d34b0a2 --- /dev/null +++ b/src/fsstone/Makefile.in @@ -0,0 +1,69 @@ +SHELL = /bin/sh +SRCS = fsstone.c +OBJS = fsstone.o +HDRS = +TESTSRC = +DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE) +CFLAGS = $(DEBUG) $(OPT) $(DEFS) +TESTPROG= +PROG = fsstone +INC_DIR = ../../include +LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \ + ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX) + +.c.o:; $(CC) $(CFLAGS) -c $*.c + +all: $(PROG) + +$(OBJS): ../../conf/makedefs.out + +Makefile: Makefile.in + cat ../../conf/makedefs.out $? >$@ + +fsstone: fsstone.o $(LIBS) + $(CC) $(CFLAGS) $(SHLIB_RPATH) -o $@ fsstone.o $(LIBS) $(SYSLIBS) + +test: $(TESTPROG) + +tests: + +root_tests: + +update: ../../libexec/fsstone + +../../libexec/fsstone: fsstone + cp $? $@ + +printfck: $(OBJS) $(PROG) + rm -rf printfck + mkdir printfck + sed '1,/^# do not edit/!d' Makefile >printfck/Makefile + set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done + cd printfck; make "INC_DIR=../../../include" `cd ..; ls *.o` +lint: + lint $(DEFS) $(SRCS) $(LINTFIX) + +clean: + rm -f *.o *core $(PROG) $(TESTPROG) junk + rm -rf printfck + +tidy: clean + +depend: $(MAKES) + (sed '1,/^# do not edit/!d' Makefile.in; \ + set -e; for i in [a-z][a-z0-9]*.c; do \ + $(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \ + -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \ + -e 's/o: \.\//o: /' -e p -e '}' ; \ + done | LANG=C sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in + @$(EXPORT) make -f Makefile.in Makefile 1>&2 + +# do not edit below this line - it is generated by 'make depend' +fsstone.o: ../../include/check_arg.h +fsstone.o: ../../include/mail_version.h +fsstone.o: ../../include/msg.h +fsstone.o: ../../include/msg_vstream.h +fsstone.o: ../../include/sys_defs.h +fsstone.o: ../../include/vbuf.h +fsstone.o: ../../include/vstream.h +fsstone.o: fsstone.c diff --git a/src/fsstone/fsstone.c b/src/fsstone/fsstone.c new file mode 100644 index 0000000..217cb04 --- /dev/null +++ b/src/fsstone/fsstone.c @@ -0,0 +1,242 @@ +/*++ +/* NAME +/* fsstone 1 +/* SUMMARY +/* measure directory operation overhead +/* SYNOPSIS +/* .fi +/* \fBfsstone\fR [\fB-cr\fR] [\fB-s \fIsize\fR] +/* \fImsg_count files_per_dir\fR +/* DESCRIPTION +/* The \fBfsstone\fR command measures the cost of creating, renaming +/* and deleting queue files versus appending messages to existing +/* files and truncating them after use. +/* +/* The program simulates the arrival of \fImsg_count\fR short messages, +/* and arranges for at most \fIfiles_per_dir\fR simultaneous files +/* in the same directory. +/* +/* Options: +/* .IP \fB-c\fR +/* Create and delete files. +/* .IP \fB-r\fR +/* Rename files twice (requires \fB-c\fR). +/* .IP \fB-s \fIsize\fR +/* Specify the file size in kbytes. +/* DIAGNOSTICS +/* Problems are reported to the standard error stream. +/* BUGS +/* The \fB-r\fR option renames files within the same directory. +/* For a more realistic simulation, the program should rename files +/* <i>between</i> directories, and should also have an option to use +/* <i>hashed</i> directories as implemented with, for example, the +/* \fBdir_forest\fR(3) module. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/*--*/ + +/* System library. */ + +#include <sys_defs.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/time.h> + +/* Utility library. */ + +#include <msg.h> +#include <msg_vstream.h> + +/* Global directory. */ + +#include <mail_version.h> + +/* rename_file - rename a file */ + +static void rename_file(int old, int new) +{ + char new_path[BUFSIZ]; + char old_path[BUFSIZ]; + + sprintf(new_path, "%06d", new); + sprintf(old_path, "%06d", old); + if (rename(old_path, new_path)) + msg_fatal("rename %s to %s: %m", old_path, new_path); +} + +/* make_file - create a little file and use it */ + +static void make_file(int seqno, int size) +{ + char path[BUFSIZ]; + char buf[1024]; + FILE *fp; + int i; + + sprintf(path, "%06d", seqno); + if ((fp = fopen(path, "w")) == 0) + msg_fatal("open %s: %m", path); + memset(buf, 'x', sizeof(buf)); + for (i = 0; i < size; i++) + if (fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf)) + msg_fatal("fwrite: %m"); + if (fsync(fileno(fp))) + msg_fatal("fsync: %m"); + if (fclose(fp)) + msg_fatal("fclose: %m"); + if ((fp = fopen(path, "r")) == 0) + msg_fatal("open %s: %m", path); + while (fgets(path, sizeof(path), fp)) + /* void */ ; + if (fclose(fp)) + msg_fatal("fclose: %m"); +} + +/* use_file - use existing file */ + +static void use_file(int seqno) +{ + char path[BUFSIZ]; + FILE *fp; + int i; + + sprintf(path, "%06d", seqno); + if ((fp = fopen(path, "w")) == 0) + msg_fatal("open %s: %m", path); + for (i = 0; i < 400; i++) + fprintf(fp, "hello"); + if (fsync(fileno(fp))) + msg_fatal("fsync: %m"); + if (fclose(fp)) + msg_fatal("fclose: %m"); + if ((fp = fopen(path, "r+")) == 0) + msg_fatal("open %s: %m", path); + while (fgets(path, sizeof(path), fp)) + /* void */ ; + if (ftruncate(fileno(fp), (off_t) 0)) + msg_fatal("ftruncate: %m");; + if (fclose(fp)) + msg_fatal("fclose: %m"); +} + +/* remove_file - delete specified file */ + +static void remove_file(int seq) +{ + char path[BUFSIZ]; + + sprintf(path, "%06d", seq); + if (remove(path)) + msg_fatal("remove %s: %m", path); +} + +/* remove_silent - delete specified file, silently */ + +static void remove_silent(int seq) +{ + char path[BUFSIZ]; + + sprintf(path, "%06d", seq); + (void) remove(path); +} + +/* usage - explain */ + +static void usage(char *myname) +{ + msg_fatal("usage: %s [-cr] [-s size] messages directory_entries", myname); +} + +MAIL_VERSION_STAMP_DECLARE; + +int main(int argc, char **argv) +{ + int op_count; + int max_file; + struct timeval start, end; + int do_rename = 0; + int do_create = 0; + int seq; + int ch; + int size = 2; + + /* + * Fingerprint executables and core dumps. + */ + MAIL_VERSION_STAMP_ALLOCATE; + + msg_vstream_init(argv[0], VSTREAM_ERR); + while ((ch = GETOPT(argc, argv, "crs:")) != EOF) { + switch (ch) { + case 'c': + do_create++; + break; + case 'r': + do_rename++; + break; + case 's': + if ((size = atoi(optarg)) <= 0) + usage(argv[0]); + break; + default: + usage(argv[0]); + } + } + + if (argc - optind != 2 || (do_rename && !do_create)) + usage(argv[0]); + if ((op_count = atoi(argv[optind])) <= 0) + usage(argv[0]); + if ((max_file = atoi(argv[optind + 1])) <= 0) + usage(argv[0]); + + /* + * Populate the directory with little files. + */ + for (seq = 0; seq < max_file; seq++) + make_file(seq, size); + + /* + * Simulate arrival and delivery of mail messages. + */ + GETTIMEOFDAY(&start); + while (op_count > 0) { + seq %= max_file; + if (do_create) { + remove_file(seq); + make_file(seq, size); + if (do_rename) { + rename_file(seq, seq + max_file); + rename_file(seq + max_file, seq); + } + } else { + use_file(seq); + } + seq++; + op_count--; + } + GETTIMEOFDAY(&end); + if (end.tv_usec < start.tv_usec) { + end.tv_sec--; + end.tv_usec += 1000000; + } + printf("elapsed time: %ld.%06ld\n", + (long) (end.tv_sec - start.tv_sec), + (long) (end.tv_usec - start.tv_usec)); + + /* + * Clean up directory fillers. + */ + for (seq = 0; seq < max_file; seq++) + remove_silent(seq); + return (0); +} |