disknice -- nice(1) for disk I/O

nice(1) is a historic Unix command to keep one process from beating the snot out of your computer's processor. Historically, this was important, as most computers had a lot of tasks and users trying to utilize one processor. Today -- not so much. Most computers have more processor cores than users, and with definite exceptions, hogging all the processor time isn't a common problem so much anymore.

Today, it's far more common to run into limitations of disk I/O than it is to run into processor I/O limitations. From time to time, I have apps that need to take place, but at their own time schedule, and preferably without slowing the experience for interactive users.

If I recall properly, I made a request some time ago to the OpenBSD mail list due to using a disk-to-disk backup to a slow writing flash storage medium. I didn't care if the task took seconds or half an hour, I did care if I felt the system run slowly becasue of it. Ted Unangst took it as a challenge and rather quickly showed this bit of code on this thread.

It may not be perfect disk scheduling, but it solved my problem very nicely.

========================================================
#include <sys/types.h>
#include <sys/wait.h>

#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.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);
}

========================================================

How it works:

This script just invokes the command you want, and SIGSTOPs and SIGCONTs it from time to time. When in the STOP state, other tasks have a chance to get to the disk subsystem.

Simple, but Works For Me.

Limitations:

Written on OpenBSD, but probably can be adopted to most Unix-like systems. Tested on Rocky Linux 9, I believe I tested it on AIX. So pretty portable as-is.

Technically, this isn't actually throttling just disk activity, but ALL activity of a program. The fact that it throttles disk I/O is just a happy effect of the program.
 
 

Holland Consulting home page
Contact Holland Consulting
 

since June 20, 2021

Page Copyright 2020, Nick Holland, Holland Consulting. Code stolen from others.