Created
November 29, 2011 16:33
-
-
Save vi/1405425 to your computer and use it in GitHub Desktop.
Simple process IO read/write rate limiter based on strace
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 7959a97980894e1a47361e566d234a5f341dd05d Mon Sep 17 00:00:00 2001 | |
From: Vitaly _Vi Shukela <vi0oss@gmail.com> | |
Date: Tue, 29 Nov 2011 19:29:50 +0300 | |
Subject: [PATCH] Strace-based speed limiter | |
Apply to strace-4.6 | |
Set env SPEEDLIMIT_READ=1000 and slow down other process with strace | |
Example: SPEEDLIMIT_READ=$((200*1024)) ./strace -o /dev/null -p `pidof wget` | |
--- | |
strace.c | 11 +++++++++++ | |
syscall.c | 29 +++++++++++++++++++++++++++++ | |
2 files changed, 40 insertions(+), 0 deletions(-) | |
diff --git a/strace.c b/strace.c | |
index 774d172..1ffb63b 100644 | |
--- a/strace.c | |
+++ b/strace.c | |
@@ -199,6 +199,10 @@ usage: strace [-CdDffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file]\n\ | |
" /* this is broken, so don't document it | |
-z -- print only succeeding syscalls\n\ | |
*/ | |
+"Set SPEEDLIMIT_READ or SPEEDLIMIT_WRITE environment variables to\n\ | |
+ bytes per seconds to slow down I/O of the traced process by\n\ | |
+ sleeping after each successfull read/write-like syscall.\n\ | |
+" | |
, DEFAULT_ACOLUMN, DEFAULT_STRLEN, DEFAULT_SORTBY); | |
exit(exitval); | |
} | |
@@ -914,6 +918,13 @@ main(int argc, char *argv[]) | |
} | |
} | |
+ extern int speedlimit_read; | |
+ extern int speedlimit_write; | |
+ speedlimit_read=0; | |
+ speedlimit_write=0; | |
+ if(getenv("SPEEDLIMIT_READ")) sscanf(getenv("SPEEDLIMIT_READ"), "%i", &speedlimit_read); | |
+ if(getenv("SPEEDLIMIT_WRITE")) sscanf(getenv("SPEEDLIMIT_WRITE"), "%i", &speedlimit_write); | |
+ | |
if ((optind == argc) == !pflag_seen) | |
usage(stderr, 1); | |
diff --git a/syscall.c b/syscall.c | |
index e66ac0a..7c2b369 100644 | |
--- a/syscall.c | |
+++ b/syscall.c | |
@@ -168,6 +168,9 @@ static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0]; | |
const char *const *errnoent; | |
int nerrnos; | |
+int speedlimit_read; | |
+int speedlimit_write; | |
+ | |
int current_personality; | |
#ifndef PERSONALITY0_WORDSIZE | |
@@ -2556,6 +2559,32 @@ trace_syscall_exiting(struct tcb *tcp) | |
} | |
printtrailer(); | |
+ if (sysent[tcp->scno].sys_func == sys_read || | |
+ sysent[tcp->scno].sys_func == sys_pread || | |
+ sysent[tcp->scno].sys_func == sys_pread64 || | |
+ sysent[tcp->scno].sys_func == sys_recv || | |
+ sysent[tcp->scno].sys_func == sys_recvfrom || | |
+ sysent[tcp->scno].sys_func == sys_readv) { | |
+ | |
+ long long int ret = tcp->u_rval; | |
+ if (ret > 0 && speedlimit_read>0) { | |
+ usleep(ret * 1000000 / speedlimit_read); | |
+ } | |
+ } else | |
+ if (sysent[tcp->scno].sys_func == sys_write || | |
+ sysent[tcp->scno].sys_func == sys_pwrite || | |
+ sysent[tcp->scno].sys_func == sys_pwrite64 || | |
+ sysent[tcp->scno].sys_func == sys_send || | |
+ sysent[tcp->scno].sys_func == sys_sendto || | |
+ sysent[tcp->scno].sys_func == sys_writev) { | |
+ | |
+ long long int ret = tcp->u_rval; | |
+ if (ret > 0 && speedlimit_write>0) { | |
+ usleep(ret * 1000000 / speedlimit_write); | |
+ } | |
+ } | |
+ | |
+ | |
dumpio(tcp); | |
if (fflush(tcp->outf) == EOF) | |
return -1; | |
-- | |
1.7.6.4 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Compiled version: http://vi-server.org/pub/strace_speedlimit