Pseudo block driver

Note: In order to start this driver, you must be logged in as root.


devb-loopback [loopback loopback_option[,option]]
              [blk option[,option]...] &

Runs on:

QNX Neutrino


Note: Use commas (,) to separate the options. You can put the blk and loopback groups of options in any order.
loopback options
The loopback options include global and order-dependent options:
  • Global options apply to all fd= instances. You can specify them anywhere in the loopback options.
  • Order-dependent options apply to all subsequent fd= files.
    Note: You can specify multiple occurrences of the order-dependent options with different values. For example, for read-only access for the first device, and read-write access for the second device, specify the following:

    loopback ro,fd=/dev/cd0,rw,fd=/fs/hd/iso.img

The global options include the following:

The number of asynchronous I/O threads (which are responsible for executing an internal block device read/write as a normal read/write over the external file descriptor). This multithreading is useful if you've specified multiple fd= devices.

The default is 1. You can specify a value of 0 to force all I/O to be performed synchronously in the context of the filesystem caller; it can be higher to prevent this I/O from becoming a bottleneck to the filesystem layers above (appropriate only when multiple fd= paths have been specified). The pool of threads services requests to all fd= files in the order of client priority.

The name by which the loopback pseudo block devices are registered. The default is lo; thus each fd= entry named on the command line appears as /dev/lo0, /dev/lo1, and so on, in order.

The order-dependent options include the following:

Specify a filename (a path registered by your resource manager) to be presented as a block device by devb-loopback. This pathname must support open(), close(), read(), write(), and fstat(); for more information, see "Driver support," below.

Each pathname results in the creation of a corresponding block-special device (see the global prefix= option), the content of which is mirrored over the file descriptor using standard read/write calls. You can then mount traditional block filesystems (such as and on top of these pseudo devices and use them transparently.

You can specify multiple fd= pathnames; they're managed by a single devb-loopback process.

rw, ro
Set the access mode to use when opening the underlying file descriptor (corresponds to O_RDWR or O_RDONLY). If you specify read-only, then in turn you can mount only read-only filesystems onto the corresponding devb-loopback device (the pseudo-device is advertised up as DEV_RDONLY). The default is rw.
sync, async
Set the synchronous write mode to use when opening the underlying file descriptor (corresponds to O_SYNC). The effect of this depends on the resource manager responsible for each file (typically it's ignored).
Note: This option affects writes that are presented to the pseudo-device, and not the write behavior of any mounted filesystems above this (that can be controlled via mount options or blk delwri=... commit=...).

The default is sync.

denyno, denyrd, denywr, denyrw
The SH_DENY* mode to use when opening the underlying file descriptor. A deny mode stops other processes from opening the host file, thus preventing its content from being changed behind the back of the devb-loopback filesystems, which prevents coherence issues. The default is denyrw.
seek, xtype
Configure I/O onto the file descriptor using either an LSEEK+READ combined message or via a READ+XTYPE_OFFSET composite. By default, devb-loopback probes the host filesystem to determine whether it supports the pread() and pwrite() API. The default is xtype.
Override the device blocksize. This is typically probed from a stat() or DCMD_CAM_DEVINFO devctl() call onto the resource manager responsible for each file and the same value advertised up, but some resource managers don't advertise a useful blocksize (in particular, devf-* reports 1-byte blocks).

You might also need this option in some cases where a filesystem image was originally formatted on a device with a different sector size to that of the hosting filesystem; it may be necessary for correct operation or performance reasons to mimic the original sector size.

This option applies to all subsequent instances of fd=, but you can reset it to use the probed value with an empty option (e.g. blksz=2048,fd=/F1,blksz=,fd=/F2).

Specify the number of heads (default 1).
Specify the number of sectors per track (default 1).
blk options
The blk options are as for If specified, they must follow the blk keyword. For more information, see

Since devb-loopback loads the standard block device DLLs, which creates a buffer cache using the same default rules as for the disk filesystems, the cache is likely to be too big for devb-loopback. You can reduce the cache size using blk cache=size. Depending on the actual size of the device, and the level of caching already implemented by its driver, a value of 128k may be sufficient.


The block filesystems in the QNX Neutrino RTOS are implemented as a series of DLL modules and a set of internal APIs. Thus it's possible to mount disk-based filesystems (such as Power-Safe or DOS) only onto released QNX devb-* drivers. The devb-loopback driver implements a mapping between an arbitrary file descriptor and the block API, allowing any resource manager to be used to host a disk filesystem.

Internal function calls, normally targeted at a SCSI/CAM driver, are translated into standard read() and write() calls onto the host file descriptor, and are used to populate the data content of a pseudo block device, which appears to the system as a disk.

Within this framework, any resource-manager or file-descriptor object can be viewed as a block-special device and be mounted as a disk filesystem. For example, you can't normally directly use an ISO9660 image stored on a devf-* device, because devf-* doesn't load fs-*.so modules; by using devb-loopback to present this image file as a block device, you can then mount it using For example:

devb-loopback fd=/devf/iso blk automount=lo0:/fs/iso:cd

This results in the following arrangement:

Other uses might be to mount images from /dev/shmem, an image filesystem (IFS), or over NFS.

The host file needs to be pregrown. For example, assuming that /fs/flash is a mounted devf filesystem, you'd have to do the following setup first:

touch /fs/flash/q4.img
dinit -hq -S32m /fs/flash/q4.img

You could then use that file on flash as a read-write filesystem:

devb-loopback blk cache=128k,auto=none loopback fd=/fs/flash/q4.img
mount -tqnx4 /dev/lo0 /q4flash

Using devb-loopback in this case adds functionality that a disk filesystem format offers (access times, hard links, etc.) to the devf-* filesystem. In other cases, devb-loopback lets you use the caching (e.g., names and sectors) that supports, but that the resource manager underlying the host file might not.

Driver support

The resource manager(s) implementing the pathnames specified by fd= operands must support the following standard interfaces:

open(), close()
The device must be able to open and close a file descriptor to it. The O_RDONLY and O_RDWR modes should be supported, as should the SH_DENY* share flags and O_SYNC modifier (if those options are used from the devb-loopback command line); the default libc iofunc open handler is suitable.
The device must support a stat method, which is used to determine the size and geometry of the underlying device. The default libc iofunc handler is suitable, provided there's an associated iofunc_mount_t which sets a suitable "blocksize" (the default is 1 byte, which isn't appropriate for use as a block device; it must be one of 512, 1024, 2048, or 4096). See also devctl() (below) and the loopback blksz= option.
read(), write()
The device must support read and write callouts, which are used to transfer "disk blocks" between the device and the filesystem buffer cache. I/O is in units of the advertised block size and within the bounds of the advertised device size. If the device supports the _IO_XTYPE_OFFSET modifier (corresponding to pread() and pwrite()), then that interface is used; otherwise a combined seek plus normal read/write is made.
If _IO_XTYPE_OFFSET isn't supported, then the device must implement an lseek method. The default libc iofunc callout is suitable.
The device may optionally implement the DCMD_CAM_DEVINFO devctl() command (refer to the <sys/dcmd_cam.h> and <sys/cam_device.h> header files). This allows the device to set certain low-level fields to fine-tune emulation behavior. The DCMD_ALL_GETFLAGS command is also used to probe the status of a (removable) file descriptor. However, suitable defaults for both these can be inferred from the fstat() query.


You can mount the filesystem image via the loopback device (/dev/lo*) from the command line with the mount command:

devb-loopback blk cache=256k,vnode=128 \
              loopback ro,blksz=2048,fd=/mnt/EFS/tts.iso &
mount -r -tcd /dev/lo0 /mnt/tts

or via the blk automount= option:

devb-loopback blk cache=256k,vnode=128,automount=lo0:/mnt/tts:cd \
              loopback ro,blksz=2048,fd=/mnt/EFS/tts.iso &

You can use umount to unmount the filesystem. The file descriptors to the underlying host image files aren't closed, and /dev/lo* remain present, until devb-loopback is terminated.