Skip to content
Merged
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
48 changes: 48 additions & 0 deletions .github/workflows/check-accessors.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
# SPDX-License-Identifier: GPL-2.0-or-later
#
# This file is part of nvme.
# Copyright (c) 2025 Dell Technologies Inc. or its subsidiaries.
#
# Authors: Martin Belanger <[email protected]>
#
# Verify that the committed accessor files (accessors.h, accessors.c) are
# up to date with the generate-accessors tool and the structs in private.h.
#
# If this check fails, run the following command and commit the result:
#
# meson compile -C <build-dir> update-accessors

name: Check accessors

on:
push:
branches: [master]
pull_request:
branches: [master]

workflow_dispatch:

jobs:
check-accessors:
name: check generated accessor files are up to date
runs-on: ubuntu-latest
container:
image: ghcr.io/linux-nvme/debian:latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Mark repo as safe for git
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Configure
run: meson setup .build-ci
- name: Regenerate accessor files
run: meson compile -C .build-ci update-accessors
- name: Check for uncommitted differences
run: |
if ! git diff --exit-code libnvme/src/nvme/accessors.h \
libnvme/src/nvme/accessors.c; then
echo ""
echo "ERROR: accessor files are out of date."
echo "Run 'meson compile -C <build-dir> update-accessors' and commit the result."
exit 1
fi
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ install: ${NAME}
uninstall:
cd ${BUILD-DIR} && meson --internal uninstall

.PHONY: update-accessors
update-accessors: ${BUILD-DIR}
meson compile -C ${BUILD-DIR} update-accessors

.PHONY: dist
dist: ${NAME}
meson dist -C ${BUILD-DIR} --formats gztar
Expand Down
89 changes: 88 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Note for nvme-cli the 'default' is set to nofallback.
#### Installing

# meson install -C .build

### Build with build.sh wrapper

The `scripts/build.sh` is used for the CI build but can also be used for
Expand Down Expand Up @@ -237,6 +237,93 @@ After that, you just need to implement the functions you defined in each
ENTRY, then append the object file name to the meson.build "sources".


### Updating the libnvme accessor functions

libnvme exposes a set of getter and setter functions (accessors) for its core
internal structs (`nvme_path`, `nvme_ns`, `nvme_ctrl`, `nvme_subsystem`,
`nvme_host`, `nvme_fabric_options`). These are generated from the struct
definitions in `libnvme/src/nvme/private.h` by the tool
`libnvme/src/nvme/generate-accessors.c`.

The generated files are committed to the source tree and are **not**
regenerated during a normal build:

```
libnvme/src/nvme/accessors.h # public API declarations (with Doxygen stubs)
libnvme/src/nvme/accessors.c # implementations
libnvme/src/nvme/accessors.ld # linker version script (manually maintained)
```

#### When to regenerate

Regeneration is needed when a struct member is added, removed, or renamed in
`private.h`, or when a struct is added to or removed from
`generate-accessors-include.list` or excluded in `generate-accessors-exclude.list`.

#### How to regenerate

```shell
$ make update-accessors
```

or equivalently:

```shell
$ meson compile -C .build update-accessors
```

The script compiles the generator, runs it, and atomically updates
`accessors.h` and `accessors.c` only when their content changes.
Commit the updated files afterward:

```shell
$ git add libnvme/src/nvme/accessors.h libnvme/src/nvme/accessors.c
$ git commit -m "libnvme: regenerate accessors following <struct> changes"
```

#### Maintaining accessors.ld

`accessors.ld` is a GNU linker version script that controls which accessor
symbols are exported from `libnvme.so` and under which ABI version label they
were introduced (e.g. `LIBNVME_ACCESSORS_3_0`).

This file is **not** updated automatically, because each symbol must be placed
in the correct version section by the maintainer. Adding a symbol to an
already-published version section would break binary compatibility for
existing users of the library.

When `make update-accessors` detects that the symbol list has drifted from
`accessors.ld`, it prints a report like the following:

```
WARNING: accessors.ld needs manual attention.

Symbols to ADD (place in a new version section, e.g. LIBNVME_ACCESSORS_X_Y):
nvme_ctrl_get_new_field
nvme_ctrl_set_new_field
```

New symbols must be added to a **new** version section that chains the
previous one. For example, if the current latest section is
`LIBNVME_ACCESSORS_3_0`, add a new section for the next release:

```
LIBNVME_ACCESSORS_3_1 {
global:
nvme_ctrl_get_new_field;
nvme_ctrl_set_new_field;
} LIBNVME_ACCESSORS_3_0;
```

Then commit `accessors.ld` together with the regenerated source files.

#### CI enforcement

A GitHub Actions workflow (`.github/workflows/check-accessors.yml`) runs on
every push and pull request. It regenerates the accessor files and fails if
the result differs from what is committed, ensuring the source tree never
drifts silently.

## Dependency

libnvme depends on the /sys/class/nvme-subsystem interface which was
Expand Down
1 change: 1 addition & 0 deletions libnvme/src/libnvme.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ extern "C" {
#include <nvme/tree.h>
#include <nvme/types.h>
#include <nvme/util.h>
#include <nvme/accessors.h>

#ifdef __cplusplus
}
Expand Down
6 changes: 3 additions & 3 deletions libnvme/src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# Authors: Martin Belanger <[email protected]>
#
sources = [
'nvme/accessors.c',
'nvme/base64.c',
'nvme/cmds.c',
'nvme/crc32.c',
Expand All @@ -29,8 +30,7 @@ else
sources += 'nvme/no-json.c'
endif

# Generate accessors (setter/getter functions)
subdir('nvme') # declares: accessors_dep, accessors_ld_full_path
subdir('nvme') # declares: accessors_ld_full_path

deps = [
config_dep,
Expand All @@ -40,7 +40,6 @@ deps = [
libdbus_dep,
liburing_dep,
openssl_dep,
accessors_dep,
]

ldfile = 'libnvme.ld'
Expand Down Expand Up @@ -98,6 +97,7 @@ install_headers(
)
install_headers(
[
'nvme/accessors.h',
'nvme/cmds.h',
'nvme/fabrics.h',
'nvme/filters.h',
Expand Down
Loading