$RodHat_
Syscall reference · I/O

ioprio_set(2)

Set a thread's I/O scheduling class and priority (ionice is the CLI wrapper).

Since
Linux 2.6.13check your kernel →
glibc
none (use syscall(2))
System
Linux
Man page
ioprio_set(2)

Synopsis

#include <linux/ioprio.h>    /* Definition of IOPRIO_* constants */
#include <sys/syscall.h>     /* Definition of SYS_* constants */
#include <unistd.h>

int syscall(SYS_ioprio_get, int which, int who);
int syscall(SYS_ioprio_set, int which, int who, int ioprio);

Rod's take

Somebody slapped nice -n 19 on the 2am backup and p99 still tripled, because nice is CPU and the backup was fighting for disk. ionice, which is ioprio_set under the hood, is the next guess, and it only does anything if the device's I/O scheduler honors priorities at all. The man page still talks about CFQ as if it's 2006; on a modern box, go read /sys/block/*/queue/scheduler before you trust it. It also admits priorities don't apply to async buffered writes. If you need real protection, cgroup v2 io.latency guards the workload that matters. ionice is a hint, not a fence.

Flags and arguments that matter

NameWhat it does
IOPRIO_WHO_PROCESSwho is a process or thread ID; 0 means the calling thread.
IOPRIO_WHO_PGRPwho is a process group ID; 0 means the caller's process group.
IOPRIO_WHO_USERwho is a UID; applies to all processes with that real UID.
IOPRIO_CLASS_RTReal-time class, levels 0-7; gets the disk first and can starve everyone. Needs CAP_SYS_ADMIN.
IOPRIO_CLASS_BEBest-effort class, levels 0 (highest) to 7; the default.
IOPRIO_CLASS_IDLEOnly gets disk time when nobody else wants it. No CAP_SYS_ADMIN needed since Linux 2.6.25.
IOPRIO_PRIO_VALUE(class, data)Macro that packs class and level into the ioprio argument.

Errors you will actually hit

errnoMeaning
EPERMNot allowed: target owned by another UID without CAP_SYS_NICE, or RT class without CAP_SYS_ADMIN.
EINVALInvalid value for which or ioprio.
ESRCHNo process matched which and who.

Example

# does this device's scheduler even look at I/O priorities?
cat /sys/block/nvme0n1/queue/scheduler

# idle class: only gets the disk when nobody else wants it
ionice -c 3 /usr/local/bin/nightly-backup
ionice -p "$pid"               # read a running process's class/priority

# what actually protects the database: cgroup v2 io.latency
mkdir /sys/fs/cgroup/database
echo "259:0 target=10" > /sys/fs/cgroup/database/io.latency
echo "$pgpid" > /sys/fs/cgroup/database/cgroup.procs

Trimmed from the full walkthrough in Stop your backup job from taking production down with it.

BSD equivalent

FreeBSD and OpenBSD: no per-process I/O priority syscall.

The long version, from the console

Sources

  1. ioprio_set(2), man7.org
  2. ionice(1), man7.org

Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.