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