From d884567cb606282d764fa63ed59a18df65f95b68 Mon Sep 17 00:00:00 2001 From: marco Date: Fri, 18 May 2007 14:48:16 +0000 Subject: [PATCH] Add timeout parameter for io run. --- sysutils/iogen/Makefile | 4 ++-- sysutils/iogen/src/iogen.8 | 6 +++++- sysutils/iogen/src/iogen.c | 38 +++++++++++++++++++++++++++++++++++--- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/sysutils/iogen/Makefile b/sysutils/iogen/Makefile index f702d143fa1..a4971f36840 100644 --- a/sysutils/iogen/Makefile +++ b/sysutils/iogen/Makefile @@ -1,7 +1,7 @@ -# $OpenBSD: Makefile,v 1.16 2007/04/16 17:46:31 marco Exp $ +# $OpenBSD: Makefile,v 1.17 2007/05/18 14:48:16 marco Exp $ COMMENT= "i/o generator" -PKGNAME= iogen-3.0 +PKGNAME= iogen-3.1 CATEGORIES= sysutils DISTFILES= diff --git a/sysutils/iogen/src/iogen.8 b/sysutils/iogen/src/iogen.8 index 5abce1c795d..8ef55381b54 100644 --- a/sysutils/iogen/src/iogen.8 +++ b/sysutils/iogen/src/iogen.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: iogen.8,v 1.7 2007/04/16 17:46:31 marco Exp $ +.\" $OpenBSD: iogen.8,v 1.8 2007/05/18 14:48:16 marco Exp $ .\" .\" Copyright (c) 2005 Marco Peereboom .\" @@ -88,6 +88,10 @@ Under heavy I/O this value can be skewed due to the asynchronous nature of .Xr alarm 3 . The default is 60 seconds. +.It Fl T Ar I/O timeout +This determines the maximum time an I/O run is allowed to take to complete. +If the timeout is reached all iogen processes will be terminated. +The default is disabled. .El .Pp Although the algorithm for I/O generation is incredibly simple, diff --git a/sysutils/iogen/src/iogen.c b/sysutils/iogen/src/iogen.c index 098c2b9fcfc..1120371fcfc 100644 --- a/sysutils/iogen/src/iogen.c +++ b/sysutils/iogen/src/iogen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: iogen.c,v 1.8 2007/04/16 17:46:31 marco Exp $ */ +/* $OpenBSD: iogen.c,v 1.9 2007/05/18 14:48:16 marco Exp $ */ /* * Copyright (c) 2005 Marco Peereboom * @@ -53,6 +53,7 @@ volatile sig_atomic_t update_res = 0; off_t file_size; off_t io_size; int interval; +int timeout = -1; int read_perc; int randomize; char target_dir[MAXPATHLEN]; @@ -141,7 +142,7 @@ err_log(int flags, const char *fmt, ...) if (flags & LOGERR) snprintf(buf, sizeof buf, "%s: %s", buf, strerror(errno_save)); - + syslog(flags & LOGFATAL ? LOG_CRIT : LOG_NOTICE, buf); if (flags & LOGKILLALL) @@ -331,6 +332,7 @@ usage(void) fprintf(stderr, "-f ; Default = iogen.res\n"); fprintf(stderr, "-n ; Default = 1\n"); fprintf(stderr, "-t ; Default = 60 seconds\n"); + fprintf(stderr, "-T ; Default = disabled\n"); fprintf(stderr, "-P ; ? displays patterns, Default = readable text\n"); fprintf(stderr, "-k kill all running io processes\n\n"); fprintf(stderr, "If parameters are omited defaults will be used.\n"); @@ -384,6 +386,19 @@ sigalarm(int sig) update_res = 1; } +void +sigtimeout(int sig) +{ + /* + * XXX we can't set a flag because IO is wedged; terminate program. + * traditional race conditions are (mostly) not applicable because + * the main loop is not running. This is not pretty but it should + * work. + */ + err_log(LOGFATAL | LOGKILLALL, + "i/o timeout (%ds) in process %i", timeout, getpid()); +} + void fill_buffer(char *buffer, size_t size, int pat) { @@ -509,6 +524,12 @@ run_io(void) "could not install ALARM handler in process %i", getpid()); + if (timeout != -1) + if (signal(SIGALRM, sigtimeout) == SIG_ERR) + err_log(LOGERR | LOGFATAL, + "could not install TIMEOUT handler in process %i", + getpid()); + /* poor mans memory test */ src = malloc(io_size); if (!src) @@ -591,6 +612,9 @@ run_io(void) alarm(interval); } + if (timeout != -1) + alarm(timeout); + /* reads */ for (i = 0; i < max_reads; i++) { io_spot = get_file_size(target_dir) / io_size - 1; @@ -686,7 +710,7 @@ main(int argc, char *argv[]) strlcpy(target_dir, "./", sizeof target_dir); strlcpy(result_dir, "./", sizeof result_dir); - while ((ch = getopt(argc, argv, "b:d:f:kn:p:rs:t:P:")) != -1) { + while ((ch = getopt(argc, argv, "b:d:f:kn:p:rs:t:T:P:")) != -1) { switch (ch) { case 'b': io_size = atoll(optarg) * @@ -755,6 +779,14 @@ main(int argc, char *argv[]) if (interval > 3600) errx(1, "time slice too large"); break; + case 'T': + timeout = atoi(optarg); + + if (timeout < 1) + errx(1, "time slice too small"); + if (timeout > 3600) + errx(1, "time slice too large"); + break; case 'P': if (optarg[0] == '?') { show_patterns();