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);
}

Reply via email to