xref: /spdk/doc/libraries.md (revision a82b365b90fca7681cb84de66f00c8a090ee45b7)
14521e05bSSeth Howell# SPDK Libraries {#libraries}
24521e05bSSeth Howell
34521e05bSSeth HowellThe SPDK repository is, first and foremost, a collection of high-performance
44521e05bSSeth Howellstorage-centric software libraries. With this in mind, much care has been taken
54521e05bSSeth Howellto ensure that these libraries have consistent and robust naming and versioning
64521e05bSSeth Howellconventions. The libraries themselves are also divided across two directories
74521e05bSSeth Howell(`lib` and `module`) inside of the SPDK repository in a deliberate way to prevent
84521e05bSSeth Howellmixing of SPDK event framework dependent code and lower level libraries. This document
94521e05bSSeth Howellis aimed at explaining the structure, naming conventions, versioning scheme, and use cases
104521e05bSSeth Howellof the libraries contained in these two directories.
114521e05bSSeth Howell
121e1fd9acSwawryk## Directory Structure {#structure}
134521e05bSSeth Howell
144521e05bSSeth HowellThe SPDK libraries are divided into two directories. The `lib` directory contains the base libraries that
154521e05bSSeth Howellcompose SPDK. Some of these base libraries define plug-in systems. Instances of those plug-ins are called
164521e05bSSeth Howellmodules and are located in the `module` directory. For example, the `spdk_sock` library is contained in the
17050df88cSTomasz Zawadzki`lib` directory while the implementations of socket abstractions, `sock_posix` and `sock_uring`
184521e05bSSeth Howellare contained in the `module` directory.
194521e05bSSeth Howell
201e1fd9acSwawryk### lib {#lib}
214521e05bSSeth Howell
224521e05bSSeth HowellThe libraries in the `lib` directory can be readily divided into four categories:
234521e05bSSeth Howell
244521e05bSSeth Howell- Utility Libraries: These libraries contain basic, commonly used functions that make more complex
254521e05bSSeth Howell  libraries easier to implement. For example, `spdk_log` contains macro definitions that provide a
264521e05bSSeth Howell  consistent logging paradigm and `spdk_json` is a general purpose JSON parsing library.
274521e05bSSeth Howell- Protocol Libraries: These libraries contain the building blocks for a specific service. For example,
284521e05bSSeth Howell  `spdk_nvmf` and `spdk_vhost` each define the storage protocols after which they are named.
294521e05bSSeth Howell- Storage Service Libraries: These libraries provide a specific abstraction that can be mapped to somewhere
304521e05bSSeth Howell  between the physical drive and the filesystem level of your typical storage stack. For example `spdk_bdev`
314521e05bSSeth Howell  provides a general block device abstraction layer, `spdk_lvol` provides a logical volume abstraction,
324521e05bSSeth Howell  `spdk_blobfs` provides a filesystem abstraction, and `spdk_ftl` provides a flash translation layer
334521e05bSSeth Howell  abstraction.
344521e05bSSeth Howell- System Libraries: These libraries provide system level services such as a JSON based RPC service
354521e05bSSeth Howell  (see `spdk_jsonrpc`) and thread abstractions (see `spdk_thread`). The most notable library in this category
364521e05bSSeth Howell  is the `spdk_env_dpdk` library which provides a shim for the underlying Data Plane Development Kit (DPDK)
374521e05bSSeth Howell  environment and provides services like memory management.
384521e05bSSeth Howell
394521e05bSSeth HowellThe one library in the `lib` directory that doesn't fit into the above classification is the `spdk_event` library.
404521e05bSSeth HowellThis library defines a framework used by the applications contained in the `app` and `example` directories. Much
414521e05bSSeth Howellcare has been taken to keep the SPDK libraries independent from this framework. The libraries in `lib` are engineered
424521e05bSSeth Howellto allow plugging directly into independent application frameworks such as Seastar or libuv with minimal effort.
434521e05bSSeth Howell
444521e05bSSeth HowellCurrently there are two exceptions in the `lib` directory which still rely on `spdk_event`, `spdk_vhost` and `spdk_iscsi`.
454521e05bSSeth HowellThere are efforts underway to remove all remaining dependencies these libraries have on the `spdk_event` library.
464521e05bSSeth Howell
474521e05bSSeth HowellMuch like the `spdk_event` library, the `spdk_env_dpdk` library has been architected in such a way that it
484521e05bSSeth Howellcan be readily replaced by an alternate environment shim. More information on replacing the `spdk_env_dpdk`
494521e05bSSeth Howellmodule and the underlying `dpdk` environment can be found in the [environment](#env_replacement) section.
504521e05bSSeth Howell
511e1fd9acSwawryk### module {#module}
524521e05bSSeth Howell
534521e05bSSeth HowellThe component libraries in the `module` directory represent specific implementations of the base libraries in
544521e05bSSeth Howellthe `lib` directory. As with the `lib` directory, much care has been taken to avoid dependencies on the
554521e05bSSeth Howell`spdk_event` framework except for those libraries which directly implement the `spdk_event` module plugin system.
564521e05bSSeth Howell
574521e05bSSeth HowellThere are seven sub-directories in the `module` directory which each hold a different class of libraries. These
584521e05bSSeth Howellsub-directories can be divided into two types.
594521e05bSSeth Howell
604521e05bSSeth Howell- plug-in libraries: These libraries are explicitly tied to one of the libraries in the `lib` directory and
614521e05bSSeth Howell  are registered with that library at runtime by way of a specific constructor function. The parent library in
624521e05bSSeth Howell  the `lib` directory then manages the module directly. These types of libraries each implement a function table
634521e05bSSeth Howell  defined by their parent library. The following table shows these directories and their corresponding parent
644521e05bSSeth Howell  libraries:
654521e05bSSeth Howell
664521e05bSSeth Howell<center>
674521e05bSSeth Howell| module directory | parent library | dependent on event library |
684521e05bSSeth Howell|------------------|----------------|----------------------------|
694521e05bSSeth Howell| module/accel     | spdk_accel     | no                         |
704521e05bSSeth Howell| module/bdev      | spdk_bdev      | no                         |
714521e05bSSeth Howell| module/event     | spdk_event     | yes                        |
724521e05bSSeth Howell| module/sock      | spdk_sock      | no                         |
734521e05bSSeth Howell</center>
744521e05bSSeth Howell
754521e05bSSeth Howell- Free libraries: These libraries are highly dependent upon a library in the `lib` directory but are not
764521e05bSSeth Howell  explicitly registered to that library via a constructor. The libraries in the `blob`, `blobfs`, and `env_dpdk`
774521e05bSSeth Howell  directories fall into this category. None of the libraries in this category depend explicitly on the
784521e05bSSeth Howell  `spdk_event` library.
794521e05bSSeth Howell
801e1fd9acSwawryk## Library Conventions {#conventions}
814521e05bSSeth Howell
824521e05bSSeth HowellThe SPDK libraries follow strict conventions for naming functions, logging, versioning, and header files.
834521e05bSSeth Howell
841e1fd9acSwawryk### Headers {#headers}
854521e05bSSeth Howell
864521e05bSSeth HowellAll public SPDK header files exist in the `include` directory of the SPDK repository. These headers
874521e05bSSeth Howellare divided into two sub-directories.
884521e05bSSeth Howell
894521e05bSSeth Howell`include/spdk` contains headers intended to be used by consumers of the SPDK libraries. All of the
904521e05bSSeth Howellfunctions, variables, and types in these functions are intended for public consumption. Multiple headers
914521e05bSSeth Howellin this directory may depend upon the same underlying library and work together to expose different facets
924521e05bSSeth Howellof the library. The `spdk_bdev` library, for example, is exposed in three different headers. `bdev_module.h`
934521e05bSSeth Howelldefines the interfaces a bdev module library would need to implement, `bdev.h` contains general block device
944521e05bSSeth Howellfunctions that would be used by an application consuming block devices exposed by SPDK, and `bdev_zone.h`
954521e05bSSeth Howellexposes zoned bdev specific functions. Many of the other libraries exhibit a similar behavior of splitting
964521e05bSSeth Howellheaders between consumers of the library and those wishing to register a module with that library.
974521e05bSSeth Howell
984521e05bSSeth Howell`include/spdk_internal`, as its name suggests contains header files intended to be consumed only by other
994521e05bSSeth Howelllibraries inside of the SPDK repository. These headers are typically used for sharing lower level functions
1004521e05bSSeth Howellbetween two libraries that both require similar functions. For example `spdk_internal/nvme_tcp.h` contains
1014521e05bSSeth Howelllow level tcp functions used by both the `spdk_nvme` and `spdk_nvmf` libraries. These headers are *NOT*
1024521e05bSSeth Howellintended for general consumption.
1034521e05bSSeth Howell
1044521e05bSSeth HowellOther header files contained directly in the `lib` and `module` directories are intended to be consumed *only*
1054521e05bSSeth Howellby source files of their corresponding library. Any symbols intended to be used across libraries need to be
1064521e05bSSeth Howellincluded in a header in the `include/spdk_internal` directory.
1074521e05bSSeth Howell
1081e1fd9acSwawryk### Naming Conventions {#naming}
1094521e05bSSeth Howell
1104521e05bSSeth HowellAll public types and functions in SPDK libraries begin with the prefix `spdk_`. They are also typically
1114521e05bSSeth Howellfurther namespaced using the spdk library name. The rest of the function or type name describes its purpose.
1124521e05bSSeth Howell
1134521e05bSSeth HowellThere are no internal library functions that begin with the `spdk_` prefix. This naming convention is
1144521e05bSSeth Howellenforced by the SPDK continuous Integration testing. Functions not intended for use outside of their home
1154521e05bSSeth Howelllibrary should be namespaced with the name of the library only.
1164521e05bSSeth Howell
1171e1fd9acSwawryk### Map Files {#map}
1184521e05bSSeth Howell
1194521e05bSSeth HowellSPDK libraries can be built as both static and shared object files. To facilitate building libraries as shared
1204521e05bSSeth Howellobjects, each one has a corresponding map file (e.g. `spdk_nvmf` relies on `spdk_nvmf.map`). SPDK libraries
1214521e05bSSeth Howellnot exporting any symbols rely on a blank map file located at `mk/spdk_blank.map`.
1224521e05bSSeth Howell
1231e1fd9acSwawryk## SPDK Shared Objects {#shared_objects}
1244521e05bSSeth Howell
1251e1fd9acSwawryk### Shared Object Versioning {#versioning}
1264521e05bSSeth Howell
1274521e05bSSeth HowellSPDK shared objects follow a semantic versioning pattern with a major and minor version. Any changes which
1284521e05bSSeth Howellbreak backwards compatibility (symbol removal or change) will cause a shared object major increment and
1294521e05bSSeth Howellbackwards compatible changes will cause a minor version increment; i.e. an application that relies on
1304521e05bSSeth Howell`libspdk_nvmf.so.3.0` will be compatible with `libspdk_nvmf.so.3.1` but not with `libspdk_nvmf.so.4.0`.
1314521e05bSSeth Howell
1324521e05bSSeth HowellShared object versions are incremented only once between each release cycle. This means that at most, the
1334521e05bSSeth Howellmajor version of each SPDK shared library will increment only once between each SPDK release.
1344521e05bSSeth Howell
1354521e05bSSeth HowellThere are currently no guarantees in SPDK of ABI compatibility between two major SPDK releases.
1364521e05bSSeth Howell
1374521e05bSSeth HowellThe point releases of an LTS release will be ABI compatible with the corresponding LTS major release.
1384521e05bSSeth Howell
1394521e05bSSeth HowellShared objects are versioned independently of one another. This means that `libspdk_nvme.so.3.0` and
1404521e05bSSeth Howell`libspdk_bdev.so.3.0` do not necessarily belong to the same release. This also means that shared objects
1414521e05bSSeth Howellwith the same suffix are not necessarily compatible with each other. It is important to source all of your
1424521e05bSSeth HowellSPDK libraries from the same repository and version to ensure inter-library compatibility.
1434521e05bSSeth Howell
1441e1fd9acSwawryk### Linking to Shared Objects {#so_linking}
1454521e05bSSeth Howell
1464521e05bSSeth HowellShared objects in SPDK are created on a per-library basis. There is a top level `libspdk.so` object
1474521e05bSSeth Howellwhich is a linker script. It simply contains references to all of the other spdk shared objects.
1484521e05bSSeth Howell
1494521e05bSSeth HowellThere are essentially two ways of linking to SPDK libraries.
1504521e05bSSeth Howell
1514521e05bSSeth Howell1. An application can link to the top level shared object library as follows:
1524521e05bSSeth Howell   ~~~{.sh}
1534521e05bSSeth Howell	gcc -o my_app ./my_app.c -lspdk -lspdk_env_dpdk -ldpdk
1544521e05bSSeth Howell   ~~~
1554521e05bSSeth Howell
1564521e05bSSeth Howell2. An application can link to only a subset of libraries by linking directly to the ones it relies on:
1574521e05bSSeth Howell   ~~~{.sh}
1584521e05bSSeth Howell	gcc -o my_app ./my_app.c -lpassthru_external -lspdk_event_bdev -lspdk_bdev -lspdk_bdev_malloc
1594521e05bSSeth Howell	-lspdk_log -lspdk_thread -lspdk_util -lspdk_event -lspdk_env_dpdk -ldpdk
1604521e05bSSeth Howell   ~~~
1614521e05bSSeth Howell
1624521e05bSSeth HowellIn the second instance, please note that applications need only link to the libraries upon which they
1634521e05bSSeth Howelldirectly depend. All SPDK libraries have their dependencies specified at object compile time. This means
1644521e05bSSeth Howellthat when linking to `spdk_net`, one does not also have to specify `spdk_log`, `spdk_util`, `spdk_json`,
1654521e05bSSeth Howell`spdk_jsonrpc`, and `spdk_rpc`. However, this dependency inclusion does not extend to the application
1664521e05bSSeth Howellitself; i.e. if an application directly uses symbols from both `spdk_bdev` and `spdk_log`, both libraries
1674521e05bSSeth Howellwill need to be supplied to the linker when linking the application even though `spdk_log` is a dependency
1684521e05bSSeth Howellof `spdk_bdev`.
1694521e05bSSeth Howell
1704521e05bSSeth HowellPlease also note that when linking to SPDK libraries, both the spdk_env shim library and the env library
1714521e05bSSeth Howellitself need to be supplied to the linker. In the examples above, these are `spdk_env_dpdk` and `dpdk`
1724521e05bSSeth Howellrespectively. This was intentional and allows one to easily swap out both the environment and the
1734521e05bSSeth Howellenvironment shim.
1744521e05bSSeth Howell
1751e1fd9acSwawryk### Replacing the env abstraction {#env_replacement}
1764521e05bSSeth Howell
1774521e05bSSeth HowellSPDK depends on an environment abstraction that provides crucial pinned memory management and PCIe
1784521e05bSSeth Howellbus management operations. The interface for this environment abstraction is defined in the
1794521e05bSSeth Howell`include/env.h` header file. The default implementation of this environment is located in `spdk_env_dpdk`.
1804521e05bSSeth HowellThis abstraction in turn relies upon the DPDK libraries. This two part implementation was deliberate
1814521e05bSSeth Howelland allows for easily swapping out the dpdk version upon which the spdk libraries rely without making
1824521e05bSSeth Howellmodifications to the spdk source directly.
1834521e05bSSeth Howell
1844521e05bSSeth HowellAny environment can replace the `spdk_env_dpdk` environment by implementing the `include/env.h` header
1854521e05bSSeth Howellfile. The environment can either be implemented wholesale in a single library or as a two-part
1864521e05bSSeth Howellshim/implementation library system.
18711d907c1Swawryk
1884521e05bSSeth Howell~~~{.sh}
1894521e05bSSeth Howell	# single library
1904521e05bSSeth Howell	gcc -o my_app ./my_app.c -lspdk -lcustom_env_implementation
1914521e05bSSeth Howell
1924521e05bSSeth Howell	# two libraries
1934521e05bSSeth Howell	gcc -o my_app ./my_app.c -lspdk -lcustom_env_shim -lcustom_env_implementation
1944521e05bSSeth Howell~~~
1951b837766SDantali0n
1961e1fd9acSwawryk## SPDK Static Objects {#static_objects}
1971b837766SDantali0n
1981b837766SDantali0nSPDK static objects are compiled by default even when no parameters are supplied to the build system.
1991b837766SDantali0nUnlike SPDK shared objects, the filename does not contain any versioning semantics. Linking against
2001b837766SDantali0nstatic objects is similar to shared objects but will always require the use of `-Wl,--whole-archive`
2011b837766SDantali0nas argument. This is due to the use of constructor functions in SPDK such as those to register
2021b837766SDantali0nNVMe transports.
2031b837766SDantali0n
2041b837766SDantali0nDue to the lack of versioning semantics, it is not recommended to install static libraries system wide.
2051b837766SDantali0nInstead the path to these static libraries should be added as argument at compile time using
2061b837766SDantali0n`-L/path/to/static/libs`. The use of static objects instead of shared objects can also be forced
207*a82b365bSJosh Sorefthrough `-Wl,-Bstatic`, otherwise some compilers might prefer to use the shared objects if both
2081b837766SDantali0nare available.
2091b837766SDantali0n
2101b837766SDantali0n~~~{.sh}
2111b837766SDantali0n	gcc -o my_app ./my_app.c -L/path/to/static/libs -Wl,--whole-archive -Wl,-Bstatic -lpassthru_external
2121b837766SDantali0n	-lspdk_event_bdev -lspdk_bdev -lspdk_bdev_malloc -lspdk_log -lspdk_thread -lspdk_util -lspdk_event
2131b837766SDantali0n	-lspdk_env_dpdk -Wl,--no-whole-archive -Wl,-Bdynamic -pthread -ldpdk
2141b837766SDantali0n~~~
215