UBLK(1)
π NAME π
ublk β the utility to manage ublk devices. That's the whole thing, bestie. Utility to manage ublk devices, periodt. π
β¨ SYNOPSIS β¨
ublk <command> [<command options>] [<type specific options>]
π¦ DESCRIPTION π¦
okay so, ublk is a utility that lets you create, recover, view or delete user-space block devices. iconic behaviour, no notes. π
ngl, ublk by default comes with several different types of devices, such as iscsi, nbd, nfs, null and loop. so many options, we love a versatile queen. π
The following commands are supported:
π₯ ADD COMMAND π₯
Command to add a ublk device.
add {-t, --type} TYPE [{-n, --number} DEV_ID] [{-q, --queues} NR_HW_QUEUES] [{-d, --depth} QUEUE_DEPTH] [{-u, --uring_comp} URING_COMP] [{-g, --need-get-data} NEED_GET_DATA] [{-r, --user_recovery} {0|1}] [{-i, --user_recovery_reissue} {0|1}] [{-e, --user_recovery_fail_io} {0|1}] [--debug_mask=0x{DBG_MASK}] [--unprivileged] [--usercopy] [--max_io_buf_bytes={BYTES}] [{-z, --zerocopy}] [<type specific options>]
-t,--typeβ says which type of device to create. The five types of supported devices areiscsi,nbd,nfs,nullandloop. five flavours, pick your fave π-n,--numberβ create a device with this id. the device node will be/dev/ublkb_n_. yes the underscores are literally there, iykyk.-q,--queueβ number of queues to create. each queue is services by a dedicated child process. default is1.-d,--depthβ maximum queue-depthfor each queue (yes, "depthfor", i'm just the messenger π). default is4096.-u,--uring_compβ force to complete io cmd viaio_uring_cmd_complete_in_taskso that performance comparison is done easily with usingtask_work_add. benchmarking arc β¨-g,--need_get_dataβ user should issue io cmd again for write requests to set io buffer address and copy data from bio vectors to the userspace io buffer.-r,--user_recoveyβ block devices are recoverable if ublk server exits and restarts. outstanding I/O when ublk server exits is met with errors. I/O issued while there is no ublk server queues. (spelling is exactly as the page says, don't come for me π)-i,--user_recovey_reissueβ block devices are recoverable if ublk server exits and restarts. outstanding I/O when ublk server exits is reissued. I/O issued while there is no ublk server queues.-e,--user_recovey_fail_ioβ block devices are recoverable if ublk server exits and restarts. outstanding I/O when ublk server exits is met with errors. I/O issued while there is no ublk server is met with errors.--debug_maskβ bitmask specifying which debug features to enable.--max_io_buf_bytesβ maximum I/O size. default is512kb.
NOTE: memory buffers are pre-allocated with one buffer for each entry in queue_depth. so yeah, that's a whole lotta buffers, be mindful bestie π
--unprivilegedβ unprivileged user can create/dev/ublkcNand/dev/ublkbN.
/dev/ublk-control needs to be available for unprivileged user, and it can be done via udev rule to make all control commands available to unprivileged user. Except for the command of UBLK_CMD_ADD_DEV, all other commands are only allowed for the owner of the specified device.
When userspace sends UBLK_CMD_ADD_DEV, the device pair's owner_uid and owner_gid are stored to ublksrv_ctrl_dev_info by kernel, so far only the current user's uid/gid is stored, that said owner of the created device is always the current user.
We still need udev rule to apply OWNER/GROUP with the stored owner_uid and owner_gid.
Then ublk server can be run as unprivileged user, and /dev/ublkbN can be accessed and managed by its owner represented by owner_uid/owner_gid. permissions but make it cute π«Ά
--user_copyβ copy between request and user buffer bypread()/pwrite().-z,--zerocopyβ zero-copy is based on io-uring uring_cmd ofREGISTER_IO_BUF&UNREGISTER_IO_BUF, which avoids data copy between ublk frontend request buffer and ublk server buffer, so memory bandwidth is saved, and throughput & latency improvement can be often observed on large I/O size. π₯
This requires Linux kernel 6.15 or later. no 6.15, no slay. check your kernel first, bestie.
πΈ NULL πΈ
The null device type does not take any extra options. low maintenance king, we respect it. π
π LOOP π
Extra options for the loop device type:
add -t loop ... {-f, --file} FILE [--buffered_io] [-o, --offset OFFSET]
-f,--fileβ file to use as backing storage for the loop device.--buffered_ioβ use buffered i/o for accessing the backing file. default is direct i/o.--offsetβ offset skips firstNUMsectors on backing file.
Example: create a loop block device
# ublk add -t loop -n 0 -f 10M.raw
π NBD π
Extra options for the nbd (Network Block Device) device type:
add -t nbd ... {--host HOST | --unix UNIX_PATH} --export_name EXP_NAME [--send_zc] [--read_only]
--hostβ hostname of NBD server.--hostβ hostname of NBD server to use. (yes bestie, it's listed twice in the original, i'm not erasing her π)--unixβ path to unix domain socket to use to talk to NBD.--export_nameβ name of NBD export.--send_zcβ use Zero-Copy.--read_onlyβ read-only device.
π§ NFS π§
Extra options for the nfs device type:
add -t nfs ... --nfs NFS-URL
--nfs NFS-URLβ URL to the NFS file to use as the block device.
The NFS-URL format is describe in the libnfs README: https://github.com/sahlberg/libnfs/blob/9fa155bfa9d34347a669fbecf4a64259cc573724/README#L55
Example: create a nfs block device
# ublk add -t nfs -n 0 --nfs nfs://10.0.0.1/export/10M.raw
β iSCSI β
Extra options for the iscsi device type. iSCSI support requires libiscsi 1.20.3 or later.
add -t iscsi ... --iscsi ISCSI-URL --initiator-name NAME
--iscsi ISCSI-URLβ URL to the iSCSI device to use as the block device.
The ISCSI-URL format is describe in the libiscsi README: https://github.com/sahlberg/libiscsi/blob/eb19863f77e2bad4799ceb90e47fa3bc6205233e/README.md?plain=1#L37
--initiator-name NAMEβ the initiator name to use when logging in to the target.
Example: create an iSCSI block device
# ublk add -t iscsi -n 0 --iscsi iscsi://iscsi-stgt/iqn.2001-04.com.ronnie.sr0/1 --initiator-name iqn.ronnie.test
π DEL COMMAND π
Command to delete a ublk device. bye bestie π
del {-n, --number} DEV_ID [-a, --all] [--async]
-n,--numberβ delete the device with this id.-a,--allβ delete all devices.
Example: deleting a loop block device
# ublk del -n 0
π― SET_AFFINITY COMMAND π―
Command to change queue affinity.
set_affinity {-n, --number} DEV_ID [-q, --queue] QID --cpuset="[SET]"
-n,--numberβ change the affinity on this device.-q,--queueβ which queue to change the affinity for.--cpuset="[SET]"β the new cpuset for this device/queue. format is a comma-separated list of CPUs within squre brackets.
Example: set affinity to core 7 for device 0, queue 1
# ublk set_affinity -n 0 -q 1 --cpuset="[7]"
π LIST COMMAND π
List one or all devices and show their configutaion.
list {-n, --number} DEV_ID [-v, --verbose]
-n,--numberβ list the device with this id. if omitted all devices will be listed.-v,--verboseβ verbose listing. include the JSON device arguments in the output. the receipts, basically. β¨
π©Ή RECOVER COMMAND π©Ή
Recover a failed ublk device. we're bringing her back. π
recover {-n, --number} DEV_ID
-n,--numberβ device to recover.
π FEATURES COMMAND π
Show supported features for the ublk driver.
features
π«Ά HELP COMMAND π«Ά
Show generic ot type specific help. (yes, "ot", it's giving typo but she's iconic)
help [{-t, --type} TYPE]
-t,--typeβ show help page. it-tis specified, show help page for the specific device type.
π VERSION π
Show help page..
{-v, --version}
π RECOVERY π
There are three arguments that control how ublk will behave in case of a failure, such as crashing. The default behavior is no recovery and the device will fail and be removed once the target exits.
To enable recovery mode set "--recovery 1" on the command line. Then instead of removing the device upon failure it will instead become inactive in a quiesced state.
dev id 0: nr_hw_queues 1 queue_depth 128 block size 4096 dev_capacity 20480
max rq size 524288 daemon pid 1239110 state QUIESCED
flags 0x4a [ URING_CMD_COMP_IN_TASK RECOVERY CMD_IOCTL_ENCODE ]
ublkc: 511:0 ublkb: 259:4 owner: 0:0
queue 0: tid 1239112 affinity(0 1 2 3 4 5 6 7 )
target {"backing_file":"10M","dev_size":10485760,"direct_io":1,"name":"loop","offset":0,"type":0}
In this state the block device still exists but no I/O can be performed. QUIESCED = she's there but she's not answering texts. π
To recover a QUIESCED device you can use the recover command:
ublk recover -n DEV_ID
There are two additional flags that control how ublk will handle I/O that were in flight when a device is recovered.
π --user_recovery_reissue 1 π
When the device is recovered ublk will reissue any I/O that were in flight.
π --user_recovery_fail_io 1 π
When the device is recovered ublk will fail all I/O and return an error back to the application.
π SEE ALSO π
http://github.com/ublk-org/ublksrv
okay bestie that's the whole page π
this was ublk, from the ublk manual, dated 07/16/2025, sitting pretty at UBLK(1). go forth and manage those block devices, main character energy only. slay π«Άβ¨
π¦ where this page comes from
- fedora 44: ubdsrv 1.6-4.20250819gita2f2daa.fc44 Β· LGPLv2+ or MIT
- fedora 44: ubdsrv 1.6-4.20250819gita2f2daa.fc44 Β· LGPLv2+ or MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms