Sync usage with man page.
[netbsd-mini2440.git] / external / ibm-public / postfix / dist / src / fsstone / fsstone.c
blob2aff95792704b46a27437a03371e071ccf9b56cd
1 /* $NetBSD$ */
3 /*++
4 /* NAME
5 /* fsstone 1
6 /* SUMMARY
7 /* measure directory operation overhead
8 /* SYNOPSIS
9 /* .fi
10 /* \fBfsstone\fR [\fB-cr\fR] [\fB-s \fIsize\fR]
11 /* \fImsg_count files_per_dir\fR
12 /* DESCRIPTION
13 /* The \fBfsstone\fR command measures the cost of creating, renaming
14 /* and deleting queue files versus appending messages to existing
15 /* files and truncating them after use.
17 /* The program simulates the arrival of \fImsg_count\fR short messages,
18 /* and arranges for at most \fIfiles_per_dir\fR simultaneous files
19 /* in the same directory.
21 /* Options:
22 /* .IP \fB-c\fR
23 /* Create and delete files.
24 /* .IP \fB-r\fR
25 /* Rename files twice (requires \fB-c\fR).
26 /* .IP \fB-s \fIsize\fR
27 /* Specify the file size in kbytes.
28 /* DIAGNOSTICS
29 /* Problems are reported to the standard error stream.
30 /* BUGS
31 /* The \fB-r\fR option renames files within the same directory.
32 /* For a more realistic simulation, the program should rename files
33 /* <i>between</i> directories, and should also have an option to use
34 /* <i>hashed</i> directories as implemented with, for example, the
35 /* \fBdir_forest\fR(3) module.
36 /* LICENSE
37 /* .ad
38 /* .fi
39 /* The Secure Mailer license must be distributed with this software.
40 /* AUTHOR(S)
41 /* Wietse Venema
42 /* IBM T.J. Watson Research
43 /* P.O. Box 704
44 /* Yorktown Heights, NY 10598, USA
45 /*--*/
47 /* System library. */
49 #include <sys_defs.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <unistd.h>
53 #include <string.h>
54 #include <sys/time.h>
56 /* Utility library. */
58 #include <msg.h>
59 #include <msg_vstream.h>
61 /* Global directory. */
63 #include <mail_version.h>
65 /* rename_file - rename a file */
67 static void rename_file(int old, int new)
69 char new_path[BUFSIZ];
70 char old_path[BUFSIZ];
72 sprintf(new_path, "%06d", new);
73 sprintf(old_path, "%06d", old);
74 if (rename(old_path, new_path))
75 msg_fatal("rename %s to %s: %m", old_path, new_path);
78 /* make_file - create a little file and use it */
80 static void make_file(int seqno, int size)
82 char path[BUFSIZ];
83 char buf[1024];
84 FILE *fp;
85 int i;
87 sprintf(path, "%06d", seqno);
88 if ((fp = fopen(path, "w")) == 0)
89 msg_fatal("open %s: %m", path);
90 memset(buf, 'x', sizeof(buf));
91 for (i = 0; i < size; i++)
92 if (fwrite(buf, 1, sizeof(buf), fp) != sizeof(buf))
93 msg_fatal("fwrite: %m");
94 if (fsync(fileno(fp)))
95 msg_fatal("fsync: %m");
96 if (fclose(fp))
97 msg_fatal("fclose: %m");
98 if ((fp = fopen(path, "r")) == 0)
99 msg_fatal("open %s: %m", path);
100 while (fgets(path, sizeof(path), fp))
101 /* void */ ;
102 if (fclose(fp))
103 msg_fatal("fclose: %m");
106 /* use_file - use existing file */
108 static void use_file(int seqno)
110 char path[BUFSIZ];
111 FILE *fp;
112 int i;
114 sprintf(path, "%06d", seqno);
115 if ((fp = fopen(path, "w")) == 0)
116 msg_fatal("open %s: %m", path);
117 for (i = 0; i < 400; i++)
118 fprintf(fp, "hello");
119 if (fsync(fileno(fp)))
120 msg_fatal("fsync: %m");
121 if (fclose(fp))
122 msg_fatal("fclose: %m");
123 if ((fp = fopen(path, "r+")) == 0)
124 msg_fatal("open %s: %m", path);
125 while (fgets(path, sizeof(path), fp))
126 /* void */ ;
127 if (ftruncate(fileno(fp), (off_t) 0))
128 msg_fatal("ftruncate: %m");;
129 if (fclose(fp))
130 msg_fatal("fclose: %m");
133 /* remove_file - delete specified file */
135 static void remove_file(int seq)
137 char path[BUFSIZ];
139 sprintf(path, "%06d", seq);
140 if (remove(path))
141 msg_fatal("remove %s: %m", path);
144 /* remove_silent - delete specified file, silently */
146 static void remove_silent(int seq)
148 char path[BUFSIZ];
150 sprintf(path, "%06d", seq);
151 (void) remove(path);
154 /* usage - explain */
156 static void usage(char *myname)
158 msg_fatal("usage: %s [-cr] [-s size] messages directory_entries", myname);
161 MAIL_VERSION_STAMP_DECLARE;
163 int main(int argc, char **argv)
165 int op_count;
166 int max_file;
167 struct timeval start, end;
168 int do_rename = 0;
169 int do_create = 0;
170 int seq;
171 int ch;
172 int size = 2;
175 * Fingerprint executables and core dumps.
177 MAIL_VERSION_STAMP_ALLOCATE;
179 msg_vstream_init(argv[0], VSTREAM_ERR);
180 while ((ch = GETOPT(argc, argv, "crs:")) != EOF) {
181 switch (ch) {
182 case 'c':
183 do_create++;
184 break;
185 case 'r':
186 do_rename++;
187 break;
188 case 's':
189 if ((size = atoi(optarg)) <= 0)
190 usage(argv[0]);
191 break;
192 default:
193 usage(argv[0]);
197 if (argc - optind != 2 || (do_rename && !do_create))
198 usage(argv[0]);
199 if ((op_count = atoi(argv[optind])) <= 0)
200 usage(argv[0]);
201 if ((max_file = atoi(argv[optind + 1])) <= 0)
202 usage(argv[0]);
205 * Populate the directory with little files.
207 for (seq = 0; seq < max_file; seq++)
208 make_file(seq, size);
211 * Simulate arrival and delivery of mail messages.
213 GETTIMEOFDAY(&start);
214 while (op_count > 0) {
215 seq %= max_file;
216 if (do_create) {
217 remove_file(seq);
218 make_file(seq, size);
219 if (do_rename) {
220 rename_file(seq, seq + max_file);
221 rename_file(seq + max_file, seq);
223 } else {
224 use_file(seq);
226 seq++;
227 op_count--;
229 GETTIMEOFDAY(&end);
230 if (end.tv_usec < start.tv_usec) {
231 end.tv_sec--;
232 end.tv_usec += 1000000;
234 printf("elapsed time: %ld.%06ld\n",
235 (long) (end.tv_sec - start.tv_sec),
236 (long) (end.tv_usec - start.tv_usec));
239 * Clean up directory fillers.
241 for (seq = 0; seq < max_file; seq++)
242 remove_silent(seq);
243 return (0);