Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,52 @@ the whole string as the path - a platform that passes a secret needs this versio

DMDEVFS uses configuration files to define and initialize device drivers. This is a critical mechanism that allows the filesystem to dynamically discover and configure hardware drivers at mount time.

### Runtime configuration sources

An existing mount accepts additional configuration directories through
`DMDEVFS_IOCTL_ADD_CONFIG` and removes them through
`DMDEVFS_IOCTL_REMOVE_CONFIG` (declared in `dmdevfs.h`). Pass a directory path
as the ioctl argument, using a file handle from that mount; its built-in
`null` node is a convenient stable control handle:

```c
void* control = Dmod_FileOpen("/dev/null", "r+");
Dmod_Ioctl(control, DMDEVFS_IOCTL_ADD_CONFIG, "/ext/cfg/drivers");
Dmod_Ioctl(control, DMDEVFS_IOCTL_ADD_CONFIG, "/mnt/SD/cfg/drivers");
// The media may already be absent: removal does not read its files.
Dmod_Ioctl(control, DMDEVFS_IOCTL_REMOVE_CONFIG, "/mnt/SD/cfg/drivers");
Dmod_FileClose(control);
```

The directory given at mount and all added directories coexist. Each node,
including hot-plug children and partitions, belongs to its source tree. The
mount keeps nodes in one `dmlist`; source records store only their path,
removal state and reference count. Withdrawn nodes stay in that list until
their source can be reclaimed and are skipped by lookups and directory reads.
Removal withdraws only that tree's nodes, reports their disappearance to
libsystemd and their friends, and preserves the other trees and the mount.
Existing handles from the removed tree fail read/write/ioctl/flush operations
with `-ENODEV`; they can still be closed. Driver contexts and modules stay
alive until the last retained reference is released. Open directory handles
retain a snapshot of nodes and skip withdrawn entries; close them to release
those references. The mount itself refuses teardown
with `-EBUSY` while handles remain open.

Commands complete synchronously, serialized with hot-plug events. Call them
from an application thread, not synchronously from a driver or service
callback invoked by the dmdevfs worker. An ADD failure rolls back that
source's new nodes; it leaves existing trees registered. Boot configuration
keeps its historical best-effort behavior for individual driver failures.

Use absolute paths. Repeated slashes, `.` components and trailing slashes are
normalized; `..` is rejected. Duplicate active sources return `-EEXIST`,
overlapping source directories return `-EINVAL`, unknown removals return
`-ENOENT`, and discovery/configuration failures return `-EIO`. A device-path
collision also fails the new source. A removed source can be added again.
The existing configuration-file path length limit still applies. This API
manages explicitly supplied sources; media detection and deciding when to
add/remove them remain the caller's responsibility.

### Overview

When DMDEVFS is mounted with a configuration path, it:
Expand Down
15 changes: 15 additions & 0 deletions include/dmdevfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@
extern "C" {
#endif

/** Runtime configuration-tree management. Pass a NUL-terminated directory
* path as arg to ioctl on any node of the target mount (prefer /dev/null).
* Calls are synchronous and run in FIFO order with hot-plug work. Do not
* call synchronously from a driver/service callback invoked by that worker.
* Paths are matched lexically, with repeated slashes and '.' normalized;
* '..' components are rejected. Use absolute paths in applications.
* ADD rejects duplicate/overlapping active trees and rolls back new nodes
* on failure. REMOVE needs no access to the source files, withdraws only
* its nodes and invalidates their handles (close remains valid). Driver
* contexts are reclaimed after the last file/directory reference is released. Returns 0 or a
* negative errno (EEXIST, EINVAL, ENOENT, EIO, ENOMEM, ENODEV, EDEADLK).
*/
#define DMDEVFS_IOCTL_ADD_CONFIG 0xF01
#define DMDEVFS_IOCTL_REMOVE_CONFIG 0xF02

// Module version
#define DMDEVFS_VERSION_MAJOR 0
#define DMDEVFS_VERSION_MINOR 2
Expand Down
Loading
Loading