I haven't really solved the problem I want to solve, but was able to whip
this up pretty quickly. Basically, it's just a wrapper that runs a
command and then starves it from running. disknice is a misnomer, it also
gets starved from cpu, but at the current time the only way to slow down a
process's io is to stop it. Not a complete solution, but it will slow
down a large tar job to the point where other programs have plenty of time
to get their requests in. The sleep ratios should be tunable, aren't.
> time disknice md5 -t
MD5 time trial. Processing 10000 10000-byte blocks...
Digest = 52e5f9c9e6f656f3e1800dfa5579d089
Time = 3.339803 seconds
Speed = 29941885.793863 bytes/second
0m3.50s real 0m0.30s user 0m0.00s system
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
int i;
char **nargv;
pid_t pid;
int status;
const int onesec = 1000000;
nargv = malloc((sizeof(*nargv) * argc + 1));
for (i = 1; i < argc; i++) {
nargv[i-1] = argv[i];
}
nargv[i-1] = NULL;
pid = fork();
if (pid == -1)
err(127, "fork");
if (!pid) {
execvp(nargv[0], nargv);
write(2, "failed to exec\n", 15);
_exit(127);
}
usleep(10);
while (!waitpid(pid, &status, WNOHANG)) {
kill(pid, SIGSTOP);
usleep(onesec / 2);
kill(pid, SIGCONT);
usleep(onesec / 10);
}
return WEXITSTATUS(status);
}