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
| Name | What it does |
|---|---|
| IOPRIO_WHO_PROCESS | who is a process or thread ID; 0 means the calling thread. |
| IOPRIO_WHO_PGRP | who is a process group ID; 0 means the caller's process group. |
| IOPRIO_WHO_USER | who is a UID; applies to all processes with that real UID. |
| IOPRIO_CLASS_RT | Real-time class, levels 0-7; gets the disk first and can starve everyone. Needs CAP_SYS_ADMIN. |
| IOPRIO_CLASS_BE | Best-effort class, levels 0 (highest) to 7; the default. |
| IOPRIO_CLASS_IDLE | Only 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
| errno | Meaning |
|---|---|
| EPERM | Not allowed: target owned by another UID without CAP_SYS_NICE, or RT class without CAP_SYS_ADMIN. |
| EINVAL | Invalid value for which or ioprio. |
| ESRCH | No 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.procsTrimmed 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
Version numbers are read off the cited man pages, not memory. Spot one that's wrong? Tell Rod.
